From 5760ebd190ac7b3e8e6463bc529df8500fa2e9d5 Mon Sep 17 00:00:00 2001 From: hosted-fornet Date: Tue, 24 Oct 2023 11:56:02 -0700 Subject: [PATCH] bring in changes from add-sqlite sans reversion --- .gitignore | 1 + build.rs | 39 +- modules/key_value/key_value/Cargo.toml | 2 +- modules/key_value/key_value/src/lib.rs | 20 +- modules/key_value/key_value_worker/Cargo.toml | 3 - modules/key_value/key_value_worker/src/lib.rs | 6 +- modules/sqlite/pkg/manifest.json | 12 + modules/sqlite/pkg/metadata.json | 4 + modules/sqlite/sqlite/Cargo.lock | 524 +++++++++++++++ modules/sqlite/sqlite/Cargo.toml | 32 + modules/sqlite/sqlite/src/kernel_types.rs | 1 + modules/sqlite/sqlite/src/lib.rs | 209 ++++++ modules/sqlite/sqlite/src/process_lib.rs | 1 + modules/sqlite/sqlite/src/sqlite_types.rs | 1 + modules/sqlite/sqlite_types.rs | 40 ++ modules/sqlite/sqlite_worker/Cargo.lock | 627 ++++++++++++++++++ modules/sqlite/sqlite_worker/Cargo.toml | 33 + modules/sqlite/sqlite_worker/build.sh | 40 ++ .../sqlite/sqlite_worker/src/kernel_types.rs | 1 + modules/sqlite/sqlite_worker/src/lib.rs | 479 +++++++++++++ .../sqlite/sqlite_worker/src/process_lib.rs | 1 + .../sqlite/sqlite_worker/src/sqlite_types.rs | 1 + src/kernel_types.rs | 2 + src/types.rs | 2 + src/vfs.rs | 40 +- 25 files changed, 2075 insertions(+), 46 deletions(-) create mode 100644 modules/sqlite/pkg/manifest.json create mode 100644 modules/sqlite/pkg/metadata.json create mode 100644 modules/sqlite/sqlite/Cargo.lock create mode 100644 modules/sqlite/sqlite/Cargo.toml create mode 120000 modules/sqlite/sqlite/src/kernel_types.rs create mode 100644 modules/sqlite/sqlite/src/lib.rs create mode 120000 modules/sqlite/sqlite/src/process_lib.rs create mode 120000 modules/sqlite/sqlite/src/sqlite_types.rs create mode 100644 modules/sqlite/sqlite_types.rs create mode 100644 modules/sqlite/sqlite_worker/Cargo.lock create mode 100644 modules/sqlite/sqlite_worker/Cargo.toml create mode 100755 modules/sqlite/sqlite_worker/build.sh create mode 120000 modules/sqlite/sqlite_worker/src/kernel_types.rs create mode 100644 modules/sqlite/sqlite_worker/src/lib.rs create mode 120000 modules/sqlite/sqlite_worker/src/process_lib.rs create mode 120000 modules/sqlite/sqlite_worker/src/sqlite_types.rs diff --git a/.gitignore b/.gitignore index 9fe56e4d..6e829f47 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ modules/**/pkg/*.wasm modules/**/wit target.wasm world +modules/sqlite/sqlite_worker/.cargo/config.toml diff --git a/build.rs b/build.rs index d2734d36..3d567f4a 100644 --- a/build.rs +++ b/build.rs @@ -62,15 +62,23 @@ fn build_app(target_path: &str, name: &str, parent_pkg_path: Option<&str>) { .unwrap(); } // Build the module targeting wasm32-wasi - run_command(Command::new("cargo").args(&[ - "build", - "--release", - "--no-default-features", - &format!("--manifest-path={}/Cargo.toml", target_path), - "--target", - "wasm32-wasi", - ])) - .unwrap(); + let bash_build_path = &format!("{}/build.sh", target_path); + if std::path::Path::new(&bash_build_path).exists() { + let cwd = std::env::current_dir().unwrap(); + std::env::set_current_dir(target_path).unwrap(); + run_command(&mut Command::new("/bin/bash").arg("build.sh")).unwrap(); + std::env::set_current_dir(cwd).unwrap(); + } else { + run_command(Command::new("cargo").args(&[ + "build", + "--release", + "--no-default-features", + &format!("--manifest-path={}/Cargo.toml", target_path), + "--target", + "wasm32-wasi", + ])) + .unwrap(); + } // Adapt module to component with adapter based on wasi_snapshot_preview1.wasm run_command(Command::new("wasm-tools").args(&[ "component", @@ -125,19 +133,22 @@ fn main() { return; } // only execute if one of the modules has source code changes - const WASI_APPS: [&str; 7] = [ + const WASI_APPS: [&str; 8] = [ "app_store", "chess", "homepage", "http_proxy", "orgs", "qns_indexer", + "sqlite", "terminal", ]; // NOT YET building KV, waiting for deps to be ready - const NESTED_WASI_APPS: [(&str, &str); 2] = [ + const NESTED_WASI_APPS: [(&str, &str); 4] = [ ("key_value", "key_value"), ("key_value", "key_value_worker"), + ("sqlite", "sqlite"), + ("sqlite", "sqlite_worker"), ]; if std::env::var("REBUILD_ALL").is_ok() { @@ -160,6 +171,7 @@ fn main() { } let pwd = std::env::current_dir().unwrap(); + // Create target.wasm (compiled .wit) & world run_command(Command::new("wasm-tools").args(&[ "component", @@ -178,11 +190,6 @@ fn main() { let entry_path = entry.unwrap().path(); let package_name = entry_path.file_name().unwrap().to_str().unwrap(); - // NOT YET building KV, waiting for deps to be ready - if package_name == "key_value" { - continue; - } - // If Cargo.toml is present, build the app let parent_pkg_path = format!("{}/pkg", entry_path.display()); if entry_path.join("Cargo.toml").exists() { diff --git a/modules/key_value/key_value/Cargo.toml b/modules/key_value/key_value/Cargo.toml index 0fd75f34..0c6d8e49 100644 --- a/modules/key_value/key_value/Cargo.toml +++ b/modules/key_value/key_value/Cargo.toml @@ -14,7 +14,7 @@ lto = true anyhow = "1.0" bincode = "1.3.3" cargo-component-bindings = { git = "https://github.com/bytecodealliance/cargo-component" } -serde = {version = "1.0", features = ["derive"] } +serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" wit-bindgen = { version = "0.11.0", default_features = false } diff --git a/modules/key_value/key_value/src/lib.rs b/modules/key_value/key_value/src/lib.rs index 4990355b..8595b3ed 100644 --- a/modules/key_value/key_value/src/lib.rs +++ b/modules/key_value/key_value/src/lib.rs @@ -79,14 +79,14 @@ fn handle_message ( } match message { - Message::Response(r) => { + Message::Response(_) => { return Err(kv::KeyValueError::UnexpectedResponse.into()); }, Message::Request(Request { ipc, .. }) => { match process_lib::parse_message_ipc(ipc.clone())? { kv::KeyValueMessage::New { ref db } => { // TODO: make atomic - // (1): create vfs + // (1): create vfs drive // (2): spin up worker, granting vfs caps // (3): issue new caps // (4): persist @@ -147,7 +147,7 @@ fn handle_message ( &Request { inherit: false, expects_response: None, - ipc, + ipc: ipc.clone(), metadata: None, }, None, @@ -156,7 +156,16 @@ fn handle_message ( // (4) db_to_process.insert(db.into(), spawned_process_id); - // TODO + // TODO: persistence? + + send_response( + &Response { + inherit: false, + ipc, + metadata: None, + }, + None, + ); }, kv::KeyValueMessage::Write { ref db, .. } => { forward_if_have_cap(our, "write", db, ipc, db_to_process)?; @@ -178,7 +187,7 @@ impl Guest for Component { fn init(our: Address) { print_to_terminal(0, "key_value: begin"); - let mut db_to_process: HashMap = HashMap::new(); + let mut db_to_process: DbToProcess = HashMap::new(); loop { match handle_message(&our, &mut db_to_process) { @@ -191,6 +200,7 @@ impl Guest for Component { if let Some(e) = e.downcast_ref::() { send_response( &Response { + inherit: false, ipc: Some(serde_json::to_string(&e).unwrap()), metadata: None, }, diff --git a/modules/key_value/key_value_worker/Cargo.toml b/modules/key_value/key_value_worker/Cargo.toml index 937b1a66..73b69436 100644 --- a/modules/key_value/key_value_worker/Cargo.toml +++ b/modules/key_value/key_value_worker/Cargo.toml @@ -30,6 +30,3 @@ package = "component:uq-process" path = "wit" [package.metadata.component.dependencies] - -[package.metadata.component.target.dependencies] -"redb:redb" = { path = "../../../../redb/wit" } diff --git a/modules/key_value/key_value_worker/src/lib.rs b/modules/key_value/key_value_worker/src/lib.rs index 2181a05b..7c892440 100644 --- a/modules/key_value/key_value_worker/src/lib.rs +++ b/modules/key_value/key_value_worker/src/lib.rs @@ -42,7 +42,7 @@ fn send_and_await_response_wrapped( }; let ( _, - Message::Response((Response { ipc, metadata }, _)), + Message::Response((Response { ipc, metadata, .. }, _)), ) = send_and_await_response( &Address { node: target_node, @@ -118,6 +118,7 @@ fn handle_message ( send_response( &Response { + inherit: false, ipc, metadata: None, }, @@ -137,6 +138,7 @@ fn handle_message ( None => { send_response( &Response { + inherit: false, ipc, metadata: None, }, @@ -155,6 +157,7 @@ fn handle_message ( ); send_response( &Response { + inherit: false, ipc, metadata: None, }, @@ -193,6 +196,7 @@ impl Guest for Component { if let Some(e) = e.downcast_ref::() { send_response( &Response { + inherit: false, ipc: Some(serde_json::to_string(&e).unwrap()), metadata: None, }, diff --git a/modules/sqlite/pkg/manifest.json b/modules/sqlite/pkg/manifest.json new file mode 100644 index 00000000..ca3522ad --- /dev/null +++ b/modules/sqlite/pkg/manifest.json @@ -0,0 +1,12 @@ +[ + { + "process_name": "sqlite", + "process_wasm_path": "/sqlite.wasm", + "on_panic": "Restart", + "request_networking": false, + "request_messaging": [ + "vfs:sys:uqbar" + ], + "public": true + } +] diff --git a/modules/sqlite/pkg/metadata.json b/modules/sqlite/pkg/metadata.json new file mode 100644 index 00000000..479571d3 --- /dev/null +++ b/modules/sqlite/pkg/metadata.json @@ -0,0 +1,4 @@ +{ + "package": "sqlite", + "publisher": "uqbar" +} diff --git a/modules/sqlite/sqlite/Cargo.lock b/modules/sqlite/sqlite/Cargo.lock new file mode 100644 index 00000000..510115a5 --- /dev/null +++ b/modules/sqlite/sqlite/Cargo.lock @@ -0,0 +1,524 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cargo-component-bindings" +version = "0.1.0" +source = "git+https://github.com/bytecodealliance/cargo-component#6a2996f280dd8671a2a2d3c83cbe09a39225b526" +dependencies = [ + "cargo-component-macro", + "wit-bindgen", +] + +[[package]] +name = "cargo-component-macro" +version = "0.1.0" +source = "git+https://github.com/bytecodealliance/cargo-component#6a2996f280dd8671a2a2d3c83cbe09a39225b526" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", + "wit-bindgen-rust-lib", + "wit-component", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "id-arena" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown", + "serde", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "memchr" +version = "2.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "pulldown-cmark" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998" +dependencies = [ + "bitflags 1.3.2", + "memchr", + "unicase", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rmp" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f9860a6cc38ed1da53456442089b4dfa35e7cedaa326df63017af88385e6b20" +dependencies = [ + "byteorder", + "num-traits", + "paste", +] + +[[package]] +name = "rmp-serde" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bffea85eea980d8a74453e5d02a8d93028f3c34725de143085a844ebe953258a" +dependencies = [ + "byteorder", + "rmp", + "serde", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "semver" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" + +[[package]] +name = "serde" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "smallvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" + +[[package]] +name = "spdx" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b19b32ed6d899ab23174302ff105c1577e45a06b08d4fe0a9dd13ce804bbbf71" +dependencies = [ + "smallvec", +] + +[[package]] +name = "sqlite" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "cargo-component-bindings", + "rmp-serde", + "serde", + "serde_json", + "thiserror", + "wit-bindgen", +] + +[[package]] +name = "syn" +version = "2.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[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 = "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.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "url" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasm-encoder" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ba64e81215916eaeb48fee292f29401d69235d62d8b8fd92a7b2844ec5ae5f7" +dependencies = [ + "leb128", +] + +[[package]] +name = "wasm-metadata" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08dc59d1fa569150851542143ca79438ca56845ccb31696c70225c638e063471" +dependencies = [ + "anyhow", + "indexmap", + "serde", + "serde_json", + "spdx", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.112.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e986b010f47fcce49cf8ea5d5f9e5d2737832f12b53ae8ae785bbe895d0877bf" +dependencies = [ + "indexmap", + "semver", +] + +[[package]] +name = "wit-bindgen" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8a3e8e965dc50e6eb4410d9a11720719fadc6a1713803ea5f3be390b81c8279" +dependencies = [ + "bitflags 2.4.0", + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77255512565dfbd0b61de466e854918041d1da53c7bc049d6188c6e02643dc1e" +dependencies = [ + "anyhow", + "wit-component", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "399c60e6ea8598d1380e792f13d557007834f0fb799fea6503408cbc5debb4ae" +dependencies = [ + "anyhow", + "heck", + "wasm-metadata", + "wit-bindgen-core", + "wit-bindgen-rust-lib", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-lib" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd9fb7a43c7dc28b0b727d6ae01bf369981229b7539e768fba2b7a4df13feeeb" +dependencies = [ + "heck", + "wit-bindgen-core", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44cea5ed784da06da0e55836a6c160e7502dbe28771c2368a595e8606243bf22" +dependencies = [ + "anyhow", + "proc-macro2", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", + "wit-bindgen-rust-lib", + "wit-component", +] + +[[package]] +name = "wit-component" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66d9f2d16dd55d1a372dcfd4b7a466ea876682a5a3cb97e71ec9eef04affa876" +dependencies = [ + "anyhow", + "bitflags 2.4.0", + "indexmap", + "log", + "serde", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e8b849bea13cc2315426b16efe6eb6813466d78f5fde69b0bb150c9c40e0dc" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "pulldown-cmark", + "semver", + "unicode-xid", + "url", +] diff --git a/modules/sqlite/sqlite/Cargo.toml b/modules/sqlite/sqlite/Cargo.toml new file mode 100644 index 00000000..a19309d2 --- /dev/null +++ b/modules/sqlite/sqlite/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "sqlite" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[profile.release] +panic = "abort" +opt-level = "s" +lto = true + +[dependencies] +anyhow = "1.0" +bincode = "1.3.3" +cargo-component-bindings = { git = "https://github.com/bytecodealliance/cargo-component" } +rmp-serde = "1.1" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +thiserror = "1.0" +wit-bindgen = { version = "0.11.0", default_features = false } + +[lib] +crate-type = ["cdylib"] + +[package.metadata.component] +package = "component:uq-process" + +[package.metadata.component.target] +path = "wit" + +[package.metadata.component.dependencies] diff --git a/modules/sqlite/sqlite/src/kernel_types.rs b/modules/sqlite/sqlite/src/kernel_types.rs new file mode 120000 index 00000000..047e48bc --- /dev/null +++ b/modules/sqlite/sqlite/src/kernel_types.rs @@ -0,0 +1 @@ +../../../../src/kernel_types.rs \ No newline at end of file diff --git a/modules/sqlite/sqlite/src/lib.rs b/modules/sqlite/sqlite/src/lib.rs new file mode 100644 index 00000000..c4c15311 --- /dev/null +++ b/modules/sqlite/sqlite/src/lib.rs @@ -0,0 +1,209 @@ +cargo_component_bindings::generate!(); + +use std::collections::HashMap; + +use bindings::component::uq_process::types::*; +use bindings::{create_capability, get_capability, Guest, has_capability, print_to_terminal, receive, send_request, send_response, spawn}; + +mod kernel_types; +use kernel_types as kt; +mod sqlite_types; +use sqlite_types as sq; +mod process_lib; + +struct Component; + +const PREFIX: &str = "sqlite-"; + +type DbToProcess = HashMap; + +fn make_vfs_cap(kind: &str, drive: &str) -> String { + serde_json::to_string(&serde_json::json!({ + "kind": kind, + "drive": drive, + })).unwrap() +} + +fn make_db_cap(kind: &str, db: &str) -> String { + serde_json::to_string(&serde_json::json!({ + "kind": kind, + "db": db, + })).unwrap() +} + +fn forward_if_have_cap( + our: &Address, + operation_type: &str, + // operation_type: OperationType, + db: &str, + ipc: Option, + db_to_process: &mut DbToProcess, +) -> anyhow::Result<()> { + if has_capability(&make_db_cap(operation_type, db)) { + // forward + let Some(process_id) = db_to_process.get(db) else { + return Err(sq::SqliteError::DbDoesNotExist.into()); + }; + send_request( + &Address { + node: our.node.clone(), + process: process_id.clone(), + }, + &Request { + inherit: true, + expects_response: None, + ipc, + metadata: None, + }, + None, + None, + ); + return Ok(()); + } else { + // reject + return Err(sq::SqliteError::NoCap.into()); + } +} + +fn handle_message ( + our: &Address, + db_to_process: &mut DbToProcess, +) -> anyhow::Result<()> { + let (source, message) = receive().unwrap(); + // let (source, message) = receive()?; + + if our.node != source.node { + return Err(sq::SqliteError::RejectForeign.into()); + } + + match message { + Message::Response(_) => { + return Err(sq::SqliteError::UnexpectedResponse.into()); + }, + Message::Request(Request { ipc, .. }) => { + match process_lib::parse_message_ipc(ipc.clone())? { + sq::SqliteMessage::New { ref db } => { + // TODO: make atomic + // (1): create vfs drive + // (2): spin up worker, granting vfs caps + // (3): issue new caps + // (4): persist + + if db_to_process.contains_key(db) { + return Err(sq::SqliteError::DbAlreadyExists.into()); + } + + // (1) + let vfs_address = Address { + node: our.node.clone(), + process: kt::ProcessId::new("vfs", "sys", "uqbar").en_wit(), + }; + let vfs_drive = format!("{}{}", PREFIX, db); + let _ = process_lib::send_and_await_response( + &vfs_address, + false, + Some(serde_json::to_string(&kt::VfsRequest { + drive: vfs_drive.clone(), + action: kt::VfsAction::New, + }).unwrap()), + None, + None, + 15, + ).unwrap(); + + // (2) + let vfs_read = get_capability( + &vfs_address, + &make_vfs_cap("read", &vfs_drive), + ).ok_or(anyhow::anyhow!("New failed: no vfs 'read' capability found"))?; + let vfs_write = get_capability( + &vfs_address, + &make_vfs_cap("write", &vfs_drive), + ).ok_or(anyhow::anyhow!("New failed: no vfs 'write' capability found"))?; + let spawned_process_id = match spawn( + None, + "/sqlite_worker.wasm", + &OnPanic::None, // TODO: notify us + &Capabilities::Some(vec![vfs_read, vfs_write]), + false, // not public + ) { + Ok(spawned_process_id) => spawned_process_id, + Err(e) => { + print_to_terminal(0, &format!("couldn't spawn: {}", e)); + panic!("couldn't spawn"); // TODO + }, + }; + // grant caps + create_capability(&source.process, &make_db_cap("read", db)); + create_capability(&source.process, &make_db_cap("write", db)); + // initialize worker + send_request( + &Address { + node: our.node.clone(), + process: spawned_process_id.clone(), + }, + &Request { + inherit: false, + expects_response: None, + ipc: ipc.clone(), + metadata: None, + }, + None, + None, + ); + + // (4) + db_to_process.insert(db.into(), spawned_process_id); + // TODO: persistence? + + send_response( + &Response { + inherit: false, + ipc, + metadata: None, + }, + None, + ); + }, + sq::SqliteMessage::Write { ref db, .. } => { + forward_if_have_cap(our, "write", db, ipc, db_to_process)?; + }, + sq::SqliteMessage::Read { ref db, .. } => { + forward_if_have_cap(our, "read", db, ipc, db_to_process)?; + }, + } + + Ok(()) + }, + } +} + +impl Guest for Component { + fn init(our: Address) { + print_to_terminal(0, "sqlite: begin"); + + let mut db_to_process: DbToProcess = HashMap::new(); + + loop { + match handle_message(&our, &mut db_to_process) { + Ok(()) => {}, + Err(e) => { + print_to_terminal(0, format!( + "sqlite: error: {:?}", + e, + ).as_str()); + if let Some(e) = e.downcast_ref::() { + send_response( + &Response { + inherit: false, + ipc: Some(serde_json::to_string(&e).unwrap()), + metadata: None, + }, + None, + ); + } + }, + }; + } + } +} diff --git a/modules/sqlite/sqlite/src/process_lib.rs b/modules/sqlite/sqlite/src/process_lib.rs new file mode 120000 index 00000000..9b9ec3f4 --- /dev/null +++ b/modules/sqlite/sqlite/src/process_lib.rs @@ -0,0 +1 @@ +../../../../src/process_lib.rs \ No newline at end of file diff --git a/modules/sqlite/sqlite/src/sqlite_types.rs b/modules/sqlite/sqlite/src/sqlite_types.rs new file mode 120000 index 00000000..0198d4ae --- /dev/null +++ b/modules/sqlite/sqlite/src/sqlite_types.rs @@ -0,0 +1 @@ +../../sqlite_types.rs \ No newline at end of file diff --git a/modules/sqlite/sqlite_types.rs b/modules/sqlite/sqlite_types.rs new file mode 100644 index 00000000..ae892a59 --- /dev/null +++ b/modules/sqlite/sqlite_types.rs @@ -0,0 +1,40 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Serialize, Deserialize)] +pub enum SqliteMessage { + New { db: String }, + Write { db: String, statement: String }, + Read { db: String, query: String }, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum SqlValue { + Integer(i64), + Real(f64), + Text(String), + Blob(Vec), +} + +pub trait Deserializable: for<'de> Deserialize<'de> + Sized { + fn from_serialized(bytes: &[u8]) -> Result { + rmp_serde::from_slice(bytes) + } +} + +impl Deserializable for Vec {} +impl Deserializable for Vec> {} + + +#[derive(Debug, Serialize, Deserialize, thiserror::Error)] +pub enum SqliteError { + #[error("DbDoesNotExist")] + DbDoesNotExist, + #[error("DbAlreadyExists")] + DbAlreadyExists, + #[error("NoCap")] + NoCap, + #[error("RejectForeign")] + RejectForeign, + #[error("UnexpectedResponse")] + UnexpectedResponse, +} diff --git a/modules/sqlite/sqlite_worker/Cargo.lock b/modules/sqlite/sqlite_worker/Cargo.lock new file mode 100644 index 00000000..f90e8de3 --- /dev/null +++ b/modules/sqlite/sqlite_worker/Cargo.lock @@ -0,0 +1,627 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", +] + +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cargo-component-bindings" +version = "0.1.0" +source = "git+https://github.com/bytecodealliance/cargo-component#6a2996f280dd8671a2a2d3c83cbe09a39225b526" +dependencies = [ + "cargo-component-macro", + "wit-bindgen", +] + +[[package]] +name = "cargo-component-macro" +version = "0.1.0" +source = "git+https://github.com/bytecodealliance/cargo-component#6a2996f280dd8671a2a2d3c83cbe09a39225b526" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", + "wit-bindgen-rust-lib", + "wit-component", +] + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[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 = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "id-arena" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown", + "serde", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + +[[package]] +name = "libc" +version = "0.2.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" + +[[package]] +name = "libsqlite3-sys" +version = "0.26.0" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "memchr" +version = "2.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "pulldown-cmark" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998" +dependencies = [ + "bitflags 1.3.2", + "memchr", + "unicase", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rmp" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f9860a6cc38ed1da53456442089b4dfa35e7cedaa326df63017af88385e6b20" +dependencies = [ + "byteorder", + "num-traits", + "paste", +] + +[[package]] +name = "rmp-serde" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bffea85eea980d8a74453e5d02a8d93028f3c34725de143085a844ebe953258a" +dependencies = [ + "byteorder", + "rmp", + "serde", +] + +[[package]] +name = "rusqlite" +version = "0.29.0" +dependencies = [ + "bitflags 2.4.0", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "semver" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" + +[[package]] +name = "serde" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "smallvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" + +[[package]] +name = "spdx" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b19b32ed6d899ab23174302ff105c1577e45a06b08d4fe0a9dd13ce804bbbf71" +dependencies = [ + "smallvec", +] + +[[package]] +name = "sqlite_worker" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "cargo-component-bindings", + "rmp-serde", + "rusqlite", + "serde", + "serde_json", + "thiserror", + "wit-bindgen", +] + +[[package]] +name = "syn" +version = "2.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[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 = "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.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "url" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[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 = "wasm-encoder" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ba64e81215916eaeb48fee292f29401d69235d62d8b8fd92a7b2844ec5ae5f7" +dependencies = [ + "leb128", +] + +[[package]] +name = "wasm-metadata" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08dc59d1fa569150851542143ca79438ca56845ccb31696c70225c638e063471" +dependencies = [ + "anyhow", + "indexmap", + "serde", + "serde_json", + "spdx", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.112.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e986b010f47fcce49cf8ea5d5f9e5d2737832f12b53ae8ae785bbe895d0877bf" +dependencies = [ + "indexmap", + "semver", +] + +[[package]] +name = "wit-bindgen" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8a3e8e965dc50e6eb4410d9a11720719fadc6a1713803ea5f3be390b81c8279" +dependencies = [ + "bitflags 2.4.0", + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77255512565dfbd0b61de466e854918041d1da53c7bc049d6188c6e02643dc1e" +dependencies = [ + "anyhow", + "wit-component", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "399c60e6ea8598d1380e792f13d557007834f0fb799fea6503408cbc5debb4ae" +dependencies = [ + "anyhow", + "heck", + "wasm-metadata", + "wit-bindgen-core", + "wit-bindgen-rust-lib", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-lib" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd9fb7a43c7dc28b0b727d6ae01bf369981229b7539e768fba2b7a4df13feeeb" +dependencies = [ + "heck", + "wit-bindgen-core", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44cea5ed784da06da0e55836a6c160e7502dbe28771c2368a595e8606243bf22" +dependencies = [ + "anyhow", + "proc-macro2", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", + "wit-bindgen-rust-lib", + "wit-component", +] + +[[package]] +name = "wit-component" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66d9f2d16dd55d1a372dcfd4b7a466ea876682a5a3cb97e71ec9eef04affa876" +dependencies = [ + "anyhow", + "bitflags 2.4.0", + "indexmap", + "log", + "serde", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e8b849bea13cc2315426b16efe6eb6813466d78f5fde69b0bb150c9c40e0dc" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "pulldown-cmark", + "semver", + "unicode-xid", + "url", +] diff --git a/modules/sqlite/sqlite_worker/Cargo.toml b/modules/sqlite/sqlite_worker/Cargo.toml new file mode 100644 index 00000000..5958bf78 --- /dev/null +++ b/modules/sqlite/sqlite_worker/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "sqlite_worker" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[profile.release] +panic = "abort" +opt-level = "s" +lto = true + +[dependencies] +anyhow = "1.0" +bincode = "1.3.3" +cargo-component-bindings = { git = "https://github.com/bytecodealliance/cargo-component" } +rmp-serde = "1.1" +rusqlite = { path = "../../../../rusqlite/", features = ["bundled", "wasm32-wasi-vfs"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +thiserror = "1.0" +wit-bindgen = { version = "0.11.0", default_features = false } + +[lib] +crate-type = ["cdylib"] + +[package.metadata.component] +package = "component:uq-process" + +[package.metadata.component.target] +path = "wit" + +[package.metadata.component.dependencies] diff --git a/modules/sqlite/sqlite_worker/build.sh b/modules/sqlite/sqlite_worker/build.sh new file mode 100755 index 00000000..673434f8 --- /dev/null +++ b/modules/sqlite/sqlite_worker/build.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +cd sqlite +cargo build --release --no-default-features --target wasm32-wasi + +cd ../sqlite_worker + +# Get special clang compiler required to build & link sqlite3 C lib. +mkdir -p target +cd target + +WASI_VERSION=20 +WASI_VERSION_FULL=${WASI_VERSION}.0 +CC_PATH=$(realpath ./wasi-sdk-${WASI_VERSION_FULL}/bin/clang) + +if [ ! -e "$CC_PATH" ]; then + wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_VERSION}/wasi-sdk-${WASI_VERSION_FULL}-linux.tar.gz + tar xvf wasi-sdk-${WASI_VERSION_FULL}-linux.tar.gz +fi + +CC_PATH=$(realpath ./wasi-sdk-${WASI_VERSION_FULL}/bin/clang) + +cd .. + +# We write env vars to `.cargo/config.toml` here because: +# 1. Doing `export foo=/path && export bar=/path2 && RUSTFLAGS=baz cargo build ...` +# does not properly pass the RUSTFLAGS (cargo bug?). +# 2. Specifying `~/path` inside `.cargo/config.toml` doesn't expand. +mkdir -p .cargo + +# CC_PATH=$(realpath ~/wasi-sdk/wasi-sdk-20.0/bin/clang) + +# Write to the .cargo/config.toml file +cat < .cargo/config.toml +[env] +CC_wasm32_wasi = "$CC_PATH" +CARGO_TARGET_WASM32_WASI_LINKER = "$CC_PATH" +EOF + +RUSTFLAGS="-C target-feature=-crt-static -C link-arg=-Wl,--no-entry,--export=init,--export=cabi_realloc" cargo build --release --no-default-features --target wasm32-wasi diff --git a/modules/sqlite/sqlite_worker/src/kernel_types.rs b/modules/sqlite/sqlite_worker/src/kernel_types.rs new file mode 120000 index 00000000..047e48bc --- /dev/null +++ b/modules/sqlite/sqlite_worker/src/kernel_types.rs @@ -0,0 +1 @@ +../../../../src/kernel_types.rs \ No newline at end of file diff --git a/modules/sqlite/sqlite_worker/src/lib.rs b/modules/sqlite/sqlite_worker/src/lib.rs new file mode 100644 index 00000000..5f65852d --- /dev/null +++ b/modules/sqlite/sqlite_worker/src/lib.rs @@ -0,0 +1,479 @@ +cargo_component_bindings::generate!(); + +use core::ffi::{c_char, c_int, c_ulonglong, CStr}; +use std::ffi::CString; + +use crate::sqlite_types::Deserializable; + +use rusqlite::{Connection, types::FromSql, types::FromSqlError, types::ToSql, types::Value, types::ValueRef}; +// use serde::{Deserialize, Serialize}; + +use bindings::component::uq_process::types::*; +use bindings::{get_payload, Guest, print_to_terminal, receive, send_and_await_response, send_response}; + +mod kernel_types; +use kernel_types as kt; +mod process_lib; +mod sqlite_types; +use sqlite_types as sq; + +struct Component; + +const PREFIX: &str = "sqlite-"; + +impl ToSql for sq::SqlValue { + fn to_sql(&self) -> rusqlite::Result { + match self { + sq::SqlValue::Integer(i) => i.to_sql(), + sq::SqlValue::Real(f) => f.to_sql(), + sq::SqlValue::Text(ref s) => s.to_sql(), + sq::SqlValue::Blob(ref b) => b.to_sql(), + } + } +} + +impl FromSql for sq::SqlValue { + fn column_result(value: ValueRef<'_>) -> Result { + match value { + ValueRef::Integer(i) => Ok(sq::SqlValue::Integer(i)), + ValueRef::Real(f) => Ok(sq::SqlValue::Real(f)), + ValueRef::Text(t) => { + let text_str = std::str::from_utf8(t).map_err(|_| FromSqlError::InvalidType)?; + Ok(sq::SqlValue::Text(text_str.to_string())) + }, + ValueRef::Blob(b) => Ok(sq::SqlValue::Blob(b.to_vec())), + _ => Err(FromSqlError::InvalidType), + } + } +} + +#[repr(C)] +pub struct CPreOptionStr { + is_empty: c_int, // 0 -> string is empty + string: CString, +} + +#[repr(C)] +pub struct COptionStr { + is_empty: c_int, // 0 -> string is empty + string: *mut c_char, +} + +#[repr(C)] +struct CBytes { + data: *mut u8, + len: usize, +} + +#[repr(C)] +pub struct CPayload { + is_empty: c_int, // 0 -> payload is empty + mime: *mut COptionStr, + bytes: *mut CBytes, +} + +#[repr(C)] +pub struct CPrePayload { + is_empty: c_int, // 0 -> payload is empty + mime: COptionStr, + bytes: CBytes, +} + +#[repr(C)] +pub struct CProcessId { + process_name: *const c_char, + package_name: *const c_char, + publisher_node: *const c_char, +} + +#[repr(C)] +pub struct CIpcMetadata { + ipc: *mut COptionStr, + metadata: *mut COptionStr, +} + +impl CPreOptionStr { + fn new(s: Option) -> Self { + let (is_empty, string) = match s { + None => (0, CString::new("").unwrap()), + Some(s) => (1, CString::new(s).unwrap()), + }; + CPreOptionStr { + is_empty, + string, + } + } +} + +impl COptionStr { + fn new(s: Option) -> Self { + let (is_empty, string) = match s { + None => (0, CString::new("").unwrap()), + Some(s) => (1, CString::new(s).unwrap()), + }; + COptionStr { + is_empty, + string: string.as_ptr() as *mut c_char, + } + } +} + +fn from_coptionstr_to_option_string(s: *const COptionStr) -> Option { + //print_to_terminal(0, "fctos"); + if unsafe { (*s).is_empty == 0 } { + None + } else { + Some(from_cstr_to_string(unsafe { (*s).string })) + } +} + +impl CBytes { + fn new(mut bytes: Vec) -> Self { + CBytes { + data: bytes.as_mut_ptr(), + len: bytes.len(), + } + } + + fn new_empty() -> Self { + CBytes::new(Vec::with_capacity(0)) + } +} + +impl From> for CBytes { + fn from(bytes: Vec) -> Self { + CBytes::new(bytes) + } +} + +impl From for Vec { + fn from(bytes: CBytes) -> Self { + let bytes = unsafe { Vec::from_raw_parts(bytes.data, bytes.len, bytes.len) }; + bytes + } +} + +fn from_cbytes_to_vec_u8(bytes: *mut CBytes) -> Vec { + // let bytes = unsafe { Vec::from_raw_parts((*bytes).data, (*bytes).len, (*bytes).len) }; + let bytes = unsafe { std::slice::from_raw_parts((*bytes).data, (*bytes).len) }; + let bytes = bytes.to_vec(); + bytes +} + +impl From> for CPrePayload { + fn from(p: Option) -> Self { + let (is_empty, mime, bytes) = match p { + None => (0, COptionStr::new(None), CBytes::new_empty()), + Some(Payload { mime, bytes }) => (1, COptionStr::new(mime), CBytes::new(bytes)), + }; + CPrePayload { + is_empty, + mime, + bytes, + } + } +} + +impl From for Option { + fn from(p: CPayload) -> Self { + if p.is_empty == 0 { + None + } else { + let mime = from_coptionstr_to_option_string(p.mime); + let bytes = from_cbytes_to_vec_u8(p.bytes); + Some(Payload { + mime, + bytes, + }) + } + } +} + +fn from_cpayload_to_option_payload(p: *const CPayload) -> Option { + if unsafe { (*p).is_empty == 0 } { + None + } else { + let mime = unsafe { from_coptionstr_to_option_string((*p).mime) }; + let bytes = unsafe { from_cbytes_to_vec_u8((*p).bytes) }; + Some(Payload { + mime, + bytes, + }) + } +} + +fn from_cprocessid_to_processid(pid: *const CProcessId) -> ProcessId { + ProcessId { + process_name: from_cstr_to_string(unsafe { (*pid).process_name }), + package_name: from_cstr_to_string(unsafe { (*pid).package_name }), + publisher_node: from_cstr_to_string(unsafe { (*pid).publisher_node }), + } +} + +fn from_cstr_to_string(s: *const c_char) -> String { + let cstr = unsafe { CStr::from_ptr(s) }; + cstr.to_str().unwrap().into() +} + +#[no_mangle] +pub extern "C" fn get_payload_wrapped(return_val: *mut CPayload) { + print_to_terminal(0, "gpw 0"); + // TODO: remove this logic; just here to avoid writing to invalid places + // in memory due to an fs bug where chunk size may be bigger than requested + let max_len = unsafe { (*(*return_val).bytes).len.clone() }; + + let payload = get_payload(); + let mime_len = { + match payload { + None => None, + Some(ref payload) => { + match payload.mime { + None => None, + Some(ref mime) => { + Some(mime.len()) + }, + } + } + } + }; + unsafe { + match payload { + None => {}, + Some(payload) => { + (*return_val).is_empty = 1; + match payload.mime { + None => {}, + Some(mime) => { + (*(*return_val).mime).is_empty = 1; + let Some(mime_len) = mime_len else { panic!("") }; + let mime = CString::new(mime).unwrap(); + std::ptr::copy_nonoverlapping( + mime.as_ptr(), + (*(*return_val).mime).string, + mime_len + 1, + ); + }, + } + (*(*return_val).bytes).len = std::cmp::min(max_len, payload.bytes.len()); + std::ptr::copy_nonoverlapping( + payload.bytes.as_ptr(), + (*(*return_val).bytes).data, + std::cmp::min(max_len, payload.bytes.len()), + ); + }, + } + } + print_to_terminal(0, "gpw: done copying"); +} + +impl CIpcMetadata { + fn copy_to_ptr(ptr: *mut CIpcMetadata, ipc: CPreOptionStr, metadata: CPreOptionStr) { + unsafe { + (*(*ptr).ipc).is_empty = ipc.is_empty; + if ipc.is_empty == 1 { + std::ptr::copy_nonoverlapping( + ipc.string.as_ptr(), + (*(*ptr).ipc).string, + ipc.string.as_bytes_with_nul().len(), + ); + } + (*(*ptr).metadata).is_empty = metadata.is_empty; + if metadata.is_empty == 1 { + std::ptr::copy_nonoverlapping( + metadata.string.as_ptr(), + (*(*ptr).metadata).string, + metadata.string.as_bytes_with_nul().len(), + ); + } + } + } +} + +#[no_mangle] +pub extern "C" fn send_and_await_response_wrapped( + target_node: *const c_char, + target_process: *const CProcessId, + request_ipc: *const COptionStr, + request_metadata: *const COptionStr, + payload: *const CPayload, + timeout: c_ulonglong, + return_val: *mut CIpcMetadata, +) { + let target_node = from_cstr_to_string(target_node); + let target_process = from_cprocessid_to_processid(target_process); + let payload = from_cpayload_to_option_payload(payload); + let request_ipc = from_coptionstr_to_option_string(request_ipc); + let request_metadata = from_coptionstr_to_option_string(request_metadata); + let ( + _, + Message::Response((Response { ipc, metadata, .. }, _)), + ) = send_and_await_response( + &Address { + node: target_node, + process: target_process, + }, + &Request { + inherit: false, + expects_response: Some(timeout), + ipc: request_ipc, + metadata: request_metadata, + }, + match payload { + None => None, + Some(ref p) => Some(p), + }, + ).unwrap() else { + panic!(""); + }; + let ipc = CPreOptionStr::new(ipc); + let metadata = CPreOptionStr::new(metadata); + + print_to_terminal(0, "saarw: copying"); + CIpcMetadata::copy_to_ptr(return_val, ipc, metadata); + print_to_terminal(0, "saarw: done copying"); +} + +#[no_mangle] +pub extern "C" fn print_to_terminal_wrapped(verbosity: c_int, content: c_int) { + print_to_terminal(verbosity as u8, &format!("sqlite(C): {}", content)); +} + +fn handle_message ( + our: &Address, + db_handle: &mut Option, +) -> anyhow::Result<()> { + let (source, message) = receive().unwrap(); + // let (source, message) = receive()?; + + if our.node != source.node { + return Err(sq::SqliteError::RejectForeign.into()); + } + + match message { + Message::Response(_) => { unimplemented!() }, + Message::Request(Request { ipc, .. }) => { + match process_lib::parse_message_ipc(ipc.clone())? { + sq::SqliteMessage::New { db } => { + let vfs_address = Address { + node: our.node.clone(), + process: kt::ProcessId::new("vfs", "sys", "uqbar").en_wit(), + }; + let vfs_drive = format!("{}{}", PREFIX, db); + + match db_handle { + Some(_) => { + return Err(anyhow::anyhow!("cannot send New more than once")); + }, + None => { + let flags = rusqlite::OpenFlags::default(); + *db_handle = Some(rusqlite::Connection::open_with_flags_and_vfs( + format!( + "{}:{}:/{}.sql", + our.node, + vfs_drive, + db, + ), + flags, + "uqbar", + )?); + }, + } + }, + sq::SqliteMessage::Write { ref statement, .. } => { + let Some(db_handle) = db_handle else { + return Err(anyhow::anyhow!("need New before Write")); + }; + + match get_payload() { + None => { + let parameters: Vec<&dyn rusqlite::ToSql> = vec![]; + db_handle.execute( + statement, + ¶meters[..], + )?; + }, + Some(Payload { mime: _, ref bytes }) => { + let parameters = Vec::::from_serialized(&bytes)?; + let parameters: Vec<&dyn rusqlite::ToSql> = parameters + .iter() + .map(|param| param as &dyn rusqlite::ToSql) + .collect(); + + db_handle.execute( + statement, + ¶meters[..], + )?; + }, + } + + send_response( + &Response { + inherit: false, + ipc, + metadata: None, + }, + None, + ); + }, + sq::SqliteMessage::Read { ref query, .. } => { + let Some(db_handle) = db_handle else { + return Err(anyhow::anyhow!("need New before Write")); + }; + + let mut statement = db_handle.prepare(query)?; + let column_names: Vec = statement + .column_names() + .iter() + .map(|c| c.to_string()) + .collect(); + let number_columns = column_names.len(); + let results: Vec> = statement + .query_map([], |row| { + (0..number_columns) + .map(|i| row.get(i)) + .collect() + })? + .map(|item| item.unwrap()) // TODO + .collect(); + + let results = rmp_serde::to_vec(&results).unwrap(); + + send_response( + &Response { + inherit: false, + ipc, + metadata: None, + }, + Some(&Payload { + mime: None, + bytes: results, + }), + ); + }, + } + + Ok(()) + }, + } +} + +impl Guest for Component { + fn init(our: Address) { + print_to_terminal(1, "sqlite_worker: begin"); + + let mut db_handle: Option = None; + + loop { + match handle_message(&our, &mut db_handle) { + Ok(()) => {}, + Err(e) => { + // TODO: should we send an error on failure? + print_to_terminal(0, format!( + "sqlite_worker: error: {:?}", + e, + ).as_str()); + }, + }; + } + } +} diff --git a/modules/sqlite/sqlite_worker/src/process_lib.rs b/modules/sqlite/sqlite_worker/src/process_lib.rs new file mode 120000 index 00000000..9b9ec3f4 --- /dev/null +++ b/modules/sqlite/sqlite_worker/src/process_lib.rs @@ -0,0 +1 @@ +../../../../src/process_lib.rs \ No newline at end of file diff --git a/modules/sqlite/sqlite_worker/src/sqlite_types.rs b/modules/sqlite/sqlite_worker/src/sqlite_types.rs new file mode 120000 index 00000000..0198d4ae --- /dev/null +++ b/modules/sqlite/sqlite_worker/src/sqlite_types.rs @@ -0,0 +1 @@ +../../sqlite_types.rs \ No newline at end of file diff --git a/src/kernel_types.rs b/src/kernel_types.rs index 4e483a08..858a93f2 100644 --- a/src/kernel_types.rs +++ b/src/kernel_types.rs @@ -298,6 +298,7 @@ pub enum VfsError { BadDriveName, BadDescriptor, NoCap, + EntryNotFound, } #[allow(dead_code)] @@ -307,6 +308,7 @@ impl VfsError { VfsError::BadDriveName => "BadDriveName", VfsError::BadDescriptor => "BadDescriptor", VfsError::NoCap => "NoCap", + VfsError::EntryNotFound => "EntryNotFound", } } } diff --git a/src/types.rs b/src/types.rs index b037ce5b..2ec3f249 100644 --- a/src/types.rs +++ b/src/types.rs @@ -593,6 +593,7 @@ pub enum VfsError { BadDriveName, BadDescriptor, NoCap, + EntryNotFound, } #[allow(dead_code)] @@ -602,6 +603,7 @@ impl VfsError { VfsError::BadDriveName => "BadDriveName", VfsError::BadDescriptor => "BadDescriptor", VfsError::NoCap => "NoCap", + VfsError::EntryNotFound => "EntryNotFound", } } } diff --git a/src/vfs.rs b/src/vfs.rs index aaefd262..575ef7e1 100644 --- a/src/vfs.rs +++ b/src/vfs.rs @@ -1098,7 +1098,7 @@ async fn match_request( }) .await .unwrap(); - panic!(""); + return Err(VfsError::EntryNotFound); }; let Some(mut entry) = vfs.key_to_entry.remove(&key) else { send_to_terminal @@ -1108,7 +1108,7 @@ async fn match_request( }) .await .unwrap(); - panic!(""); + return Err(VfsError::EntryNotFound); }; match entry.entry_type { EntryType::Dir { .. } => { @@ -1160,7 +1160,7 @@ async fn match_request( }) .await .unwrap(); - panic!(""); + return Err(VfsError::EntryNotFound); }; let Some(entry) = vfs.key_to_entry.remove(&key) else { send_to_terminal @@ -1170,7 +1170,7 @@ async fn match_request( }) .await .unwrap(); - panic!(""); + return Err(VfsError::EntryNotFound); }; match entry.entry_type { EntryType::Dir { @@ -1228,7 +1228,7 @@ async fn match_request( let file_hash = { let mut vfs = vfs.lock().await; let Some(key) = vfs.path_to_key.remove(&full_path) else { - panic!(""); + return Err(VfsError::EntryNotFound); }; let key2 = key.clone(); let Key::File { id: file_hash } = key2 else { @@ -1282,7 +1282,7 @@ async fn match_request( let file_hash = { let mut vfs = vfs.lock().await; let Some(key) = vfs.path_to_key.remove(&full_path) else { - panic!(""); // TODO + return Err(VfsError::EntryNotFound); }; let key2 = key.clone(); let Key::File { id: file_hash } = key2 else { @@ -1352,12 +1352,16 @@ async fn match_request( } VfsAction::GetHash(full_path) => { let vfs = vfs.lock().await; - let mut ipc = Some(serde_json::to_string(&VfsResponse::GetHash(None)).unwrap()); - if let Some(key) = vfs.path_to_key.get(&full_path) { - if let Key::File { id: hash } = key { - ipc = Some(serde_json::to_string(&VfsResponse::GetHash(Some(*hash))).unwrap()); - }; - } + let Some(key) = vfs.path_to_key.get(&full_path) else { + return Err(VfsError::EntryNotFound); + }; + let ipc = Some( + serde_json::to_string(&VfsResponse::GetHash(match key { + Key::File { id } => Some(id.clone()), + Key::Dir { .. } => None, + })) + .unwrap(), + ); (ipc, None) } VfsAction::GetEntry(ref full_path) => { @@ -1406,14 +1410,10 @@ async fn match_request( } }; - let entry_not_found = ( - Some(serde_json::to_string(&VfsResponse::Err(VfsError::BadDescriptor)).unwrap()), - None, - ); match key { - None => entry_not_found, + None => return Err(VfsError::EntryNotFound), Some(key) => match entry { - None => entry_not_found, + None => return Err(VfsError::EntryNotFound), Some(entry) => match entry.entry_type { EntryType::Dir { parent: _, @@ -1503,7 +1503,7 @@ async fn match_request( let file_hash = { let mut vfs = vfs.lock().await; let Some(key) = vfs.path_to_key.remove(full_path) else { - panic!(""); // TODO + return Err(VfsError::EntryNotFound); }; let key2 = key.clone(); let Key::File { id: file_hash } = key2 else { @@ -1577,7 +1577,7 @@ async fn match_request( let file_hash = { let mut vfs = vfs.lock().await; let Some(key) = vfs.path_to_key.remove(full_path) else { - panic!(""); + return Err(VfsError::EntryNotFound); }; let key2 = key.clone(); let Key::File { id: file_hash } = key2 else {