From de465aafb1fb73d3976c0ab98e8dc8b0adaca293 Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Sun, 2 Jun 2024 19:12:03 -0400 Subject: [PATCH] add stuff --- Cargo.lock | 383 +++++++++++++++++- crates/panorama-daemon/Cargo.toml | 1 + crates/panorama-daemon/data/base_fields.json | 36 ++ .../data/base_fields_schema.json | 36 ++ crates/panorama-daemon/src/main.rs | 37 +- crates/panorama-daemon/src/migrations.rs | 15 +- crates/panorama-daemon/src/node.rs | 44 +- crates/panorama-daemon/src/state.rs | 50 +++ 8 files changed, 559 insertions(+), 43 deletions(-) create mode 100644 crates/panorama-daemon/data/base_fields.json create mode 100644 crates/panorama-daemon/data/base_fields_schema.json create mode 100644 crates/panorama-daemon/src/state.rs diff --git a/Cargo.lock b/Cargo.lock index ec96bda..f52c635 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,6 +65,12 @@ dependencies = [ "alloc-no-stdlib", ] +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -104,6 +110,12 @@ dependencies = [ "derive_arbitrary", ] +[[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" @@ -458,6 +470,15 @@ dependencies = [ "serde", ] +[[package]] +name = "bitpacking" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c1d3e2bfd8d06048a179f7b17afc3188effa10385e7b00dc65af6aae732ea92" +dependencies = [ + "crunchy", +] + [[package]] name = "block" version = "0.1.6" @@ -645,6 +666,12 @@ dependencies = [ "smallvec", ] +[[package]] +name = "census" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f4c707c6a209cbe82d10abd08e1ea8995e9ea937d2550646e02798948992be0" + [[package]] name = "cesu8" version = "1.1.0" @@ -1001,6 +1028,12 @@ version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +[[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" @@ -1333,6 +1366,12 @@ dependencies = [ "litrs", ] +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + [[package]] name = "dpi" version = "0.1.1" @@ -1504,6 +1543,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "fastdivide" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59668941c55e5c186b8b58c391629af56774ec768f73c08bbcd56f09348eb00b" + [[package]] name = "fastrand" version = "2.1.0" @@ -1581,6 +1626,16 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs4" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73969b81e8bc90a3828d913dd3973d80771bfb9d7fbe1a78a79122aad456af15" +dependencies = [ + "rustix", + "windows-sys 0.52.0", +] + [[package]] name = "futf" version = "0.1.5" @@ -1814,6 +1869,20 @@ dependencies = [ "windows 0.48.0", ] +[[package]] +name = "generator" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186014d53bc231d0090ef8d6f03e0920c54d85a5ed22f4f2f74315ec56cf83fb" +dependencies = [ + "cc", + "cfg-if", + "libc", + "log", + "rustversion", + "windows 0.54.0", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -1978,7 +2047,7 @@ dependencies = [ "fxhash", "linereader", "log", - "memmap2", + "memmap2 0.5.10", "num", "num-format", "num_cpus", @@ -2073,6 +2142,10 @@ name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash 0.8.11", + "allocator-api2", +] [[package]] name = "heck" @@ -2112,6 +2185,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "htmlescape" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9025058dae765dee5070ec375f591e2ba14638c63feff74f13805a72e523163" + [[package]] name = "http" version = "1.1.0" @@ -2328,6 +2407,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", ] [[package]] @@ -2521,6 +2603,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "levenshtein_automata" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2cdeb66e45e9f36bfad5bbdb4d2384e70936afbee843c6f6543f0c551ebb25" + [[package]] name = "libappindicator" version = "0.9.0" @@ -2571,6 +2659,12 @@ dependencies = [ "windows-targets 0.52.5", ] +[[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" @@ -2640,7 +2734,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" dependencies = [ "cfg-if", - "generator", + "generator 0.7.5", "scoped-tls", "serde", "serde_json", @@ -2648,6 +2742,29 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "loom" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if", + "generator 0.8.1", + "pin-utils", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "lru" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" +dependencies = [ + "hashbrown 0.14.5", +] + [[package]] name = "lz4-sys" version = "1.9.4" @@ -2667,6 +2784,12 @@ dependencies = [ "twox-hash", ] +[[package]] +name = "lz4_flex" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75761162ae2b0e580d7e7c390558127e5f01b4194debd6221fd8c207fc80e3f5" + [[package]] name = "mac" version = "0.1.1" @@ -2727,6 +2850,16 @@ dependencies = [ "rawpointer", ] +[[package]] +name = "measure_time" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbefd235b0aadd181626f281e1d684e116972988c14c264e42069d5e8a5775cc" +dependencies = [ + "instant", + "log", +] + [[package]] name = "memchr" version = "2.7.2" @@ -2742,6 +2875,15 @@ dependencies = [ "libc", ] +[[package]] +name = "memmap2" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" +dependencies = [ + "libc", +] + [[package]] name = "memoffset" version = "0.9.1" @@ -2858,6 +3000,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "murmurhash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2195bf6aa996a481483b29d62a7663eed3fe39600c460e323f8ff41e90bdd89b" + [[package]] name = "nanorand" version = "0.7.0" @@ -3038,6 +3186,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -3086,7 +3235,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 2.0.2", "proc-macro2", "quote", "syn 2.0.66", @@ -3234,6 +3383,15 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "oneshot" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071d1cf3298ad8e543dca18217d198cb6a3884443d204757b9624b935ef09fa0" +dependencies = [ + "loom 0.7.2", +] + [[package]] name = "open" version = "5.1.3" @@ -3286,6 +3444,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "ownedbytes" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3a059efb063b8f425b948e042e6b9bd85edfe60e913630ed727b23e2dfcc558" +dependencies = [ + "stable_deref_trait", +] + [[package]] name = "owo-colors" version = "3.5.0" @@ -3358,6 +3525,7 @@ dependencies = [ "serde", "serde_json", "sugars", + "tantivy", "tokio", "tower", "tower-http", @@ -3897,6 +4065,16 @@ dependencies = [ "getrandom 0.2.15", ] +[[package]] +name = "rand_distr" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + [[package]] name = "rand_hc" version = "0.2.0" @@ -4594,6 +4772,15 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +[[package]] +name = "sketches-ddsketch" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85636c14b73d81f541e525f585c0a2109e6744e1565b5c1668e31c70c10ed65c" +dependencies = [ + "serde", +] + [[package]] name = "slab" version = "0.4.9" @@ -4738,7 +4925,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b8c4a4445d81357df8b1a650d0d0d6fbbbfe99d064aa5e02f3e4022061476d8" dependencies = [ - "loom", + "loom 0.5.6", ] [[package]] @@ -4838,7 +5025,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec5f895272298fe2ed7c8f15dcee10b00ce396c8caebd602275fd10f49797d02" dependencies = [ "bincode", - "lz4_flex", + "lz4_flex 0.10.0", "miniz_oxide", "serde", "tempfile", @@ -4923,6 +5110,148 @@ dependencies = [ "version-compare", ] +[[package]] +name = "tantivy" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8d0582f186c0a6d55655d24543f15e43607299425c5ad8352c242b914b31856" +dependencies = [ + "aho-corasick", + "arc-swap", + "base64 0.22.1", + "bitpacking", + "byteorder", + "census", + "crc32fast", + "crossbeam-channel", + "downcast-rs", + "fastdivide", + "fnv", + "fs4", + "htmlescape", + "itertools 0.12.1", + "levenshtein_automata", + "log", + "lru", + "lz4_flex 0.11.3", + "measure_time", + "memmap2 0.9.4", + "num_cpus", + "once_cell", + "oneshot", + "rayon", + "regex", + "rust-stemmers", + "rustc-hash", + "serde", + "serde_json", + "sketches-ddsketch", + "smallvec", + "tantivy-bitpacker", + "tantivy-columnar", + "tantivy-common", + "tantivy-fst", + "tantivy-query-grammar", + "tantivy-stacker", + "tantivy-tokenizer-api", + "tempfile", + "thiserror", + "time", + "uuid", + "winapi", + "zstd", +] + +[[package]] +name = "tantivy-bitpacker" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "284899c2325d6832203ac6ff5891b297fc5239c3dc754c5bc1977855b23c10df" +dependencies = [ + "bitpacking", +] + +[[package]] +name = "tantivy-columnar" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12722224ffbe346c7fec3275c699e508fd0d4710e629e933d5736ec524a1f44e" +dependencies = [ + "downcast-rs", + "fastdivide", + "itertools 0.12.1", + "serde", + "tantivy-bitpacker", + "tantivy-common", + "tantivy-sstable", + "tantivy-stacker", +] + +[[package]] +name = "tantivy-common" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8019e3cabcfd20a1380b491e13ff42f57bb38bf97c3d5fa5c07e50816e0621f4" +dependencies = [ + "async-trait", + "byteorder", + "ownedbytes", + "serde", + "time", +] + +[[package]] +name = "tantivy-fst" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d60769b80ad7953d8a7b2c70cdfe722bbcdcac6bccc8ac934c40c034d866fc18" +dependencies = [ + "byteorder", + "regex-syntax 0.8.3", + "utf8-ranges", +] + +[[package]] +name = "tantivy-query-grammar" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "847434d4af57b32e309f4ab1b4f1707a6c566656264caa427ff4285c4d9d0b82" +dependencies = [ + "nom", +] + +[[package]] +name = "tantivy-sstable" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c69578242e8e9fc989119f522ba5b49a38ac20f576fc778035b96cc94f41f98e" +dependencies = [ + "tantivy-bitpacker", + "tantivy-common", + "tantivy-fst", + "zstd", +] + +[[package]] +name = "tantivy-stacker" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c56d6ff5591fc332739b3ce7035b57995a3ce29a93ffd6012660e0949c956ea8" +dependencies = [ + "murmurhash32", + "rand_distr", + "tantivy-common", +] + +[[package]] +name = "tantivy-tokenizer-api" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0dcade25819a89cfe6f17d932c9cedff11989936bf6dd4f336d50392053b04" +dependencies = [ + "serde", +] + [[package]] name = "tao" version = "0.28.0" @@ -5832,6 +6161,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8-ranges" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcfc827f90e53a02eaef5e535ee14266c1d569214c6aa70133a624d8a3164ba" + [[package]] name = "utoipa" version = "5.0.0-alpha.0" @@ -6212,6 +6547,16 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" +dependencies = [ + "windows-core 0.54.0", + "windows-targets 0.52.5", +] + [[package]] name = "windows" version = "0.56.0" @@ -6231,6 +6576,16 @@ dependencies = [ "windows-targets 0.52.5", ] +[[package]] +name = "windows-core" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" +dependencies = [ + "windows-result", + "windows-targets 0.52.5", +] + [[package]] name = "windows-core" version = "0.56.0" @@ -6686,6 +7041,24 @@ dependencies = [ "thiserror", ] +[[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" diff --git a/crates/panorama-daemon/Cargo.toml b/crates/panorama-daemon/Cargo.toml index 859ad4b..0cd1a2b 100644 --- a/crates/panorama-daemon/Cargo.toml +++ b/crates/panorama-daemon/Cargo.toml @@ -18,6 +18,7 @@ miette = "5.5.0" serde = { version = "1.0.202", features = ["derive"] } serde_json = "1.0.117" sugars = "3.0.1" +tantivy = { version = "0.22.0", features = ["zstd"] } tokio = { version = "1.37.0", features = ["full"] } tower = "0.4.13" tower-http = { version = "0.5.2", features = ["cors"] } diff --git a/crates/panorama-daemon/data/base_fields.json b/crates/panorama-daemon/data/base_fields.json new file mode 100644 index 0000000..89fd6cc --- /dev/null +++ b/crates/panorama-daemon/data/base_fields.json @@ -0,0 +1,36 @@ +{ + "$schema": "./base_fields_schema.json", + "fields": [ + { + "fq_field_name": "/journal/page/content", + "relation_name": "content", + "relation_field_name": "string", + "type": "string", + "is_fts_enabled": true + }, + { + "fq_field_name": "/mail/config/imap_hostname", + "relation_name": "mail_config", + "relation_field_name": "imap_hostname", + "type": "string" + }, + { + "fq_field_name": "/mail/config/imap_port", + "relation_name": "mail_config", + "relation_field_name": "imap_port", + "type": "int" + }, + { + "fq_field_name": "/mail/config/imap_username", + "relation_name": "mail_config", + "relation_field_name": "imap_username", + "type": "string" + }, + { + "fq_field_name": "/mail/config/imap_password", + "relation_name": "mail_config", + "relation_field_name": "imap_password", + "type": "string" + } + ] +} diff --git a/crates/panorama-daemon/data/base_fields_schema.json b/crates/panorama-daemon/data/base_fields_schema.json new file mode 100644 index 0000000..c49cbbe --- /dev/null +++ b/crates/panorama-daemon/data/base_fields_schema.json @@ -0,0 +1,36 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "fields": { + "type": "array", + "items": { + "type": "object", + "required": [ + "fq_field_name", + "relation_name", + "relation_field_name", + "type" + ], + "properties": { + "fq_field_name": { + "type": "string" + }, + "relation_name": { + "type": "string" + }, + "relation_field_name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "is_fts_enabled": { + "type": "boolean" + } + } + } + } + }, + "title": "Base Panorama Fields" +} diff --git a/crates/panorama-daemon/src/main.rs b/crates/panorama-daemon/src/main.rs index 85dad51..37a88e7 100644 --- a/crates/panorama-daemon/src/main.rs +++ b/crates/panorama-daemon/src/main.rs @@ -14,6 +14,7 @@ mod mail; mod migrations; mod node; mod query_builder; +pub mod state; use std::fs; @@ -23,28 +24,21 @@ use axum::{ routing::{get, post, put}, Router, }; -use cozo::DbInstance; use serde_json::Value; use tokio::net::TcpListener; use tower::ServiceBuilder; use tower_http::cors::{self, CorsLayer}; use utoipa::OpenApi; use utoipa_scalar::{Scalar, Servable}; -use utoipa_swagger_ui::SwaggerUi; use crate::{ export::export, journal::get_todays_journal_id, - mail::{get_mail, get_mail_config, mail_loop}, - migrations::run_migrations, - node::{create_node, get_node, node_types, search_nodes, update_node}, + mail::{get_mail, get_mail_config}, + node::{create_node, node_types, search_nodes, update_node}, + state::AppState, }; -#[derive(Clone)] -pub struct AppState { - db: DbInstance, -} - #[tokio::main] async fn main() -> Result<()> { #[derive(OpenApi)] @@ -56,21 +50,9 @@ async fn main() -> Result<()> { let data_dir = dirs::data_dir().unwrap(); let panorama_dir = data_dir.join("panorama"); - let db_path = panorama_dir.join("db.sqlite"); - fs::create_dir_all(panorama_dir)?; + fs::create_dir_all(&panorama_dir)?; - let db = DbInstance::new( - "sqlite", - db_path.display().to_string(), - Default::default(), - ) - .unwrap(); - - run_migrations(&db).await?; - - tokio::spawn(mail_loop(db.clone())); - - let state = AppState { db }; + let state = AppState::new(&panorama_dir).await?; let cors = CorsLayer::new() .allow_methods([Method::GET, Method::POST, Method::PUT]) @@ -88,14 +70,15 @@ async fn main() -> Result<()> { .route("/export", get(export)) .route("/node", put(create_node)) .route("/node/search", get(search_nodes)) - .route("/node/:id", get(get_node)) - .route("/node/:id", post(update_node)) + // .route("/node/:id", get(get_node)) + // .route("/node/:id", post(update_node)) .route("/node/types", get(node_types)) + .nest("/node", node::router().with_state(state.clone())) .route("/journal/get_todays_journal_id", get(get_todays_journal_id)) .route("/mail/config", get(get_mail_config)) .route("/mail", get(get_mail)) .layer(ServiceBuilder::new().layer(cors)) - .with_state(state); + .with_state(state.clone()); let listener = TcpListener::bind("0.0.0.0:5195").await?; println!("Listening... {:?}", listener); diff --git a/crates/panorama-daemon/src/migrations.rs b/crates/panorama-daemon/src/migrations.rs index f34b381..085bb49 100644 --- a/crates/panorama-daemon/src/migrations.rs +++ b/crates/panorama-daemon/src/migrations.rs @@ -125,17 +125,18 @@ fn migration_01(db: &DbInstance) -> Result<()> { relation: String, field_name: String, type: String, + fts_enabled: Bool, } } { - ?[key, relation, field_name, type] <- [ - ['panorama/journal/page/content', 'journal', 'content', 'string'], - ['panorama/mail/config/imap_hostname', 'mail_config', 'imap_hostname', 'string'], - ['panorama/mail/config/imap_port', 'mail_config', 'imap_port', 'int'], - ['panorama/mail/config/imap_username', 'mail_config', 'imap_username', 'string'], - ['panorama/mail/config/imap_password', 'mail_config', 'imap_password', 'string'], + ?[key, relation, field_name, type, fts_enabled] <- [ + ['panorama/journal/page/content', 'journal', 'content', 'string', true], + ['panorama/mail/config/imap_hostname', 'mail_config', 'imap_hostname', 'string', false], + ['panorama/mail/config/imap_port', 'mail_config', 'imap_port', 'int', false], + ['panorama/mail/config/imap_username', 'mail_config', 'imap_username', 'string', false], + ['panorama/mail/config/imap_password', 'mail_config', 'imap_password', 'string', false], ] - :put fqkey_to_dbkey { key, relation, field_name, type } + :put fqkey_to_dbkey { key, relation, field_name, type, fts_enabled } } # Create journal type diff --git a/crates/panorama-daemon/src/node.rs b/crates/panorama-daemon/src/node.rs index c43c924..017f46d 100644 --- a/crates/panorama-daemon/src/node.rs +++ b/crates/panorama-daemon/src/node.rs @@ -1,9 +1,13 @@ -use std::collections::{BTreeMap, HashMap}; +use std::{ + collections::{BTreeMap, HashMap}, + result, +}; use axum::{ extract::{Path, Query, State}, http::StatusCode, - Json, + routing::get, + Json, Router, }; use cozo::{DataValue, DbInstance, MultiTransaction, ScriptMutability, Vector}; use itertools::Itertools; @@ -13,10 +17,15 @@ use uuid::Uuid; use crate::{error::AppResult, AppState}; +/// Node API #[derive(OpenApi)] #[openapi(paths(get_node), components(schemas(GetNodeResult)))] pub(super) struct NodeApi; +pub(super) fn router() -> Router { + Router::new().route("/:id", get(get_node)) +} + #[derive(Serialize, Deserialize, ToSchema, Clone)] struct GetNodeResult { node: String, @@ -29,17 +38,34 @@ struct GetNodeResult { title: String, } +/// Get all info about a single node #[utoipa::path( get, path = "/{id}", responses( - (status = 200, description = "Get all info about a single node", body = [GetNodeResult]) - ) + (status = 200, body = [GetNodeResult]) + ), + params( + ("id" = String, Path, description = "Node ID"), + ), )] pub async fn get_node( State(state): State, Path(node_id): Path, ) -> AppResult<(StatusCode, Json)> { + let result = state.db.run_script( + " + ?[relation, field_name, type, fts_enabled] := + *node_has_key { key, id }, + *fqkey_to_dbkey { key, relation, field_name, type, fts_enabled }, + id = $node_id + ", + btmap! {"node_id".to_owned() => node_id.clone().into()}, + ScriptMutability::Immutable, + )?; + + println!("FIRST RESULT: {:?}", result); + let result = state.db.run_script( " j[content] := *journal{ node_id, content }, node_id = $node_id @@ -89,6 +115,16 @@ pub struct UpdateData { extra_data: Option, } +#[utoipa::path( + post, + path = "/{id}", + responses( + (status = 200) + ), + params( + ("id" = String, Path, description = "Node ID"), + ) +)] pub async fn update_node( State(state): State, Path(node_id): Path, diff --git a/crates/panorama-daemon/src/state.rs b/crates/panorama-daemon/src/state.rs new file mode 100644 index 0000000..ac42350 --- /dev/null +++ b/crates/panorama-daemon/src/state.rs @@ -0,0 +1,50 @@ +use std::{fs, path::Path}; + +use anyhow::Result; +use cozo::DbInstance; +use tantivy::{ + directory::MmapDirectory, + schema::{self, Schema, STORED, STRING, TEXT}, + Index, +}; + +use crate::{mail::mail_loop, migrations::run_migrations}; + +#[derive(Clone)] +pub struct AppState { + pub db: DbInstance, + pub tantivy_index: Index, +} + +impl AppState { + pub async fn new(panorama_dir: impl AsRef) -> Result { + let panorama_dir = panorama_dir.as_ref().to_path_buf(); + println!("Panorama dir: {}", panorama_dir.display()); + + let tantivy_index = { + let mut schema_builder = Schema::builder(); + let node_id = schema_builder.add_text_field("node_id", STRING | STORED); + let title = schema_builder.add_text_field("title", TEXT | STORED); + let body = schema_builder.add_text_field("body", TEXT); + let schema = schema_builder.build(); + let tantivy_path = panorama_dir.join("tantivy-index"); + fs::create_dir_all(&tantivy_path)?; + let dir = MmapDirectory::open(&tantivy_path)?; + Index::builder().schema(schema).open_or_create(dir)? + }; + + let db_path = panorama_dir.join("db.sqlite"); + let db = DbInstance::new( + "sqlite", + db_path.display().to_string(), + Default::default(), + ) + .unwrap(); + + run_migrations(&db).await?; + + tokio::spawn(mail_loop(db.clone())); + + Ok(AppState { db, tantivy_index }) + } +}