From 786c69d84021a40dca3eaef6ad77851461bd1e78 Mon Sep 17 00:00:00 2001 From: Jeff Baskin Date: Tue, 27 Sep 2022 07:31:59 -0400 Subject: [PATCH] Added initial elements for SQL. --- Cargo.lock | 386 ++++++----------------------------- Cargo.toml | 6 +- src/main.rs | 4 + src/morethantext/error.rs | 187 ++++------------- src/morethantext/mod.rs | 185 +++++++++++------ src/morethantext/mttsql.pest | 8 + src/morethantext/old-mod2.rs | 120 +++++++++++ 7 files changed, 363 insertions(+), 533 deletions(-) create mode 100644 src/morethantext/mttsql.pest create mode 100644 src/morethantext/old-mod2.rs diff --git a/Cargo.lock b/Cargo.lock index f6e8aad..d691003 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,16 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "Inflector" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" -dependencies = [ - "lazy_static", - "regex", -] - [[package]] name = "aead" version = "0.3.2" @@ -77,15 +67,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "aho-corasick" -version = "0.7.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" -dependencies = [ - "memchr", -] - [[package]] name = "anyhow" version = "1.0.55" @@ -104,12 +85,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" -[[package]] -name = "ascii_utils" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71938f30533e4d95a6d17aa530939da3842c2ab6f4f84b9dae68447e4129f74a" - [[package]] name = "async-attributes" version = "1.1.2" @@ -171,76 +146,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "async-graphql" -version = "4.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffffea596a12b6d9ea5c6fc8a5f414cf4e0c8cd6b618ac2c3d4f56d9b5c5520b" -dependencies = [ - "async-graphql-derive", - "async-graphql-parser", - "async-graphql-value", - "async-stream", - "async-trait", - "bytes", - "fast_chemail", - "fnv", - "futures-util", - "http", - "indexmap", - "mime", - "multer", - "num-traits", - "once_cell", - "pin-project-lite 0.2.8", - "regex", - "serde", - "serde_json", - "static_assertions", - "tempfile", - "thiserror", -] - -[[package]] -name = "async-graphql-derive" -version = "4.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7082221cc1dc29edec0e3225420146b1fbc7f18ba534e301eab186501ae84c28" -dependencies = [ - "Inflector", - "async-graphql-parser", - "darling", - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", - "thiserror", -] - -[[package]] -name = "async-graphql-parser" -version = "4.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c328e2cb0dade64333859f7a7e22c9e19a3767afaad673976a1d855c9bda5ffa" -dependencies = [ - "async-graphql-value", - "pest", - "serde", - "serde_json", -] - -[[package]] -name = "async-graphql-value" -version = "4.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "005292494ce718604a0dc1531e5827fe540761e1df44b064085711c5fde70b7c" -dependencies = [ - "bytes", - "indexmap", - "serde", - "serde_json", -] - [[package]] name = "async-h1" version = "2.3.3" @@ -375,27 +280,6 @@ dependencies = [ "wasm-bindgen-futures", ] -[[package]] -name = "async-stream" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e" -dependencies = [ - "async-stream-impl", - "futures-core", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "async-task" version = "4.1.0" @@ -535,15 +419,6 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" -[[package]] -name = "bytes" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" -dependencies = [ - "serde", -] - [[package]] name = "cache-padded" version = "1.2.0" @@ -712,41 +587,6 @@ dependencies = [ "cipher", ] -[[package]] -name = "darling" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4529658bdda7fd6769b8614be250cdcfc3aeb0ee72fe66f9e41e5e5eb73eac02" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "649c91bc01e8b1eac09fb91e8dbc7d517684ca6be8ebc75bb9cafc894f9fdb6f" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn", -] - -[[package]] -name = "darling_macro" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc69c5bfcbd2fc09a0f38451d2daf0e372e367986a83906d1b0dbc88134fb5" -dependencies = [ - "darling_core", - "quote", - "syn", -] - [[package]] name = "dashmap" version = "4.0.2" @@ -757,6 +597,19 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "dashmap" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" +dependencies = [ + "cfg-if 1.0.0", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "digest" version = "0.8.1" @@ -787,15 +640,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" -[[package]] -name = "encoding_rs" -version = "0.8.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" -dependencies = [ - "cfg-if 1.0.0", -] - [[package]] name = "event-listener" version = "2.5.2" @@ -808,15 +652,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" -[[package]] -name = "fast_chemail" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "495a39d30d624c2caabe6312bfead73e7717692b44e0b32df168c275a2e8e9e4" -dependencies = [ - "ascii_utils", -] - [[package]] name = "fastrand" version = "1.7.0" @@ -842,12 +677,6 @@ dependencies = [ "web-sys", ] -[[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.0.1" @@ -858,6 +687,21 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futures" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.21" @@ -865,6 +709,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -873,6 +718,17 @@ version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +[[package]] +name = "futures-executor" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + [[package]] name = "futures-io" version = "0.3.21" @@ -907,9 +763,9 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" +checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56" [[package]] name = "futures-task" @@ -923,6 +779,7 @@ version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" dependencies = [ + "futures-channel", "futures-core", "futures-io", "futures-macro", @@ -999,9 +856,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ "ahash", ] @@ -1045,17 +902,6 @@ dependencies = [ "digest 0.9.0", ] -[[package]] -name = "http" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - [[package]] name = "http-client" version = "6.5.1" @@ -1064,7 +910,7 @@ checksum = "ea880b03c18a7e981d7fb3608b8904a98425d53c440758fcebf7d934aa56547c" dependencies = [ "async-trait", "cfg-if 1.0.0", - "dashmap", + "dashmap 4.0.2", "http-types", "log", ] @@ -1097,12 +943,6 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9100414882e15fb7feccb4897e5f0ff0ff1ca7d1a86a23208ada4d7a18e6c6c4" -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "idna" version = "0.2.3" @@ -1114,17 +954,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "indexmap" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" -dependencies = [ - "autocfg", - "hashbrown", - "serde", -] - [[package]] name = "infer" version = "0.2.3" @@ -1195,9 +1024,9 @@ checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" [[package]] name = "lock_api" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +checksum = "9f80bf5aacaf25cbfc8210d1cfb718f2bf3b11c4c54e5afe36c236853a8ec390" dependencies = [ "autocfg", "scopeguard", @@ -1257,34 +1086,16 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" name = "morethantext_web" version = "0.1.0" dependencies = [ - "async-graphql", "async-std", "config", + "pest", + "pest_derive", "serde", - "serde_json", "serial_test", "tide", "tide-testing", ] -[[package]] -name = "multer" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f8f35e687561d5c1667590911e6698a8cb714a134a7505718a182e7bc9d3836" -dependencies = [ - "bytes", - "encoding_rs", - "futures-util", - "http", - "httparse", - "log", - "memchr", - "mime", - "spin", - "version_check", -] - [[package]] name = "nom" version = "7.1.1" @@ -1326,9 +1137,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.9.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" +checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e" [[package]] name = "opaque-debug" @@ -1504,16 +1315,6 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" -[[package]] -name = "proc-macro-crate" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" -dependencies = [ - "thiserror", - "toml", -] - [[package]] name = "proc-macro-error" version = "1.0.4" @@ -1635,39 +1436,13 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.13" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags", ] -[[package]] -name = "regex" -version = "1.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" - -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "ron" version = "0.7.0" @@ -1704,12 +1479,6 @@ dependencies = [ "semver", ] -[[package]] -name = "rustversion" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" - [[package]] name = "ryu" version = "1.0.9" @@ -1793,10 +1562,12 @@ dependencies = [ [[package]] name = "serial_test" -version = "0.7.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d19dbfb999a147cedbfe82f042eb9555f5b0fa4ef95ee4570b74349103d9c9f4" +checksum = "92761393ee4dc3ff8f4af487bd58f4307c9329bbedea02cac0089ad9c411e153" dependencies = [ + "dashmap 5.4.0", + "futures", "lazy_static", "log", "parking_lot", @@ -1805,14 +1576,13 @@ dependencies = [ [[package]] name = "serial_test_derive" -version = "0.7.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb9e2050b2be1d681f8f1c1a528bcfe4e00afa2d8995f713974f5333288659f2" +checksum = "4b6f5d1c3087fb119617cff2966fe3808a80e5eb59a8c1601d5994d66f4346a5" dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "rustversion", "syn", ] @@ -1892,9 +1662,9 @@ checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" [[package]] name = "smallvec" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" [[package]] name = "socket2" @@ -1906,12 +1676,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "spin" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c530c2b0d0bf8b69304b39fe2001993e267461948b890cd037d8ad4293fa1a0d" - [[package]] name = "standback" version = "0.2.17" @@ -1921,12 +1685,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "stdweb" version = "0.4.20" @@ -1976,12 +1734,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "subtle" version = "2.4.1" @@ -2025,20 +1777,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "tempfile" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if 1.0.0", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] - [[package]] name = "thiserror" version = "1.0.30" diff --git a/Cargo.toml b/Cargo.toml index 24ca893..9aa41e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,11 +6,13 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -async-graphql = "*" +#async-graphql = "*" async-std = { version = "*", features = ["attributes"] } config = "*" +pest = "*" +pest_derive = "*" serde = "*" -serde_json = "*" +#serde_json = "*" tide = "*" [dev-dependencies] diff --git a/src/main.rs b/src/main.rs index 98c5002..0086c54 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,7 @@ +extern crate pest; +#[macro_use] +extern crate pest_derive; + use tide::{ http::StatusCode, sessions::{MemoryStore, SessionMiddleware}, diff --git a/src/morethantext/error.rs b/src/morethantext/error.rs index 6d58580..af80adf 100644 --- a/src/morethantext/error.rs +++ b/src/morethantext/error.rs @@ -1,195 +1,90 @@ -use std::{error::Error, fmt, sync::Arc}; +use std::{error::Error, fmt}; #[derive(Debug)] -pub enum MTTError { - Generic(Generic), +pub struct DBError { + msg: String, + src: Option>, } -impl MTTError { - pub fn new(detail: S) -> Self - where - S: Into, - { - Generic::new(detail).into() - } - - pub fn add_source(&mut self, source: E) - where - E: Into, - { - match self { - MTTError::Generic(err) => err.add_source(source), - } - } -} - -impl Error for MTTError { - fn source(&self) -> Option<&(dyn Error + 'static)> { - match self { - MTTError::Generic(err) => err.source(), - } - } -} - -impl fmt::Display for MTTError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - MTTError::Generic(err) => write!(f, "{}", err), - } - } -} - -impl From for MTTError { - fn from(err: Generic) -> Self { - MTTError::Generic(err) - } -} - -#[derive(Debug)] -pub struct Generic { - detail: String, - source: Option>, -} - -impl Generic { - fn new(detail: S) -> Self +impl DBError { + pub fn new(msg: S) -> Self where S: Into, { Self { - detail: detail.into(), - source: None, + msg: msg.into(), + src: None, } } - fn add_source(&mut self, source: E) + pub fn add_source(&mut self, src: E) where - E: Into, + E: Error + 'static, { - self.source = Some(Arc::new(source.into())); + self.src = Some(Box::new(src)); } } -impl Error for Generic { +impl Error for DBError { fn source(&self) -> Option<&(dyn Error + 'static)> { - match &self.source { + match &self.src { Some(err) => Some(err.as_ref()), None => None, } } } -impl fmt::Display for Generic { +impl fmt::Display for DBError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.detail) + write!(f, "{}", self.msg) } } #[cfg(test)] -mod mtterror { +mod create { use super::*; #[test] - fn create_with_str() { - let detail = "Something"; - let err = MTTError::new(detail); + fn with_str() { + let msg = "something happened"; + let err = DBError::new(msg); assert!( - err.to_string() == detail, - "\n\nGot: {}\nWant: {}\n\n", + err.to_string() == msg, + "Got: {} -- Want: {}", err.to_string(), - detail + msg ); assert!( err.source().is_none(), - "Error source should initialoze to None." + "Error should initialize with no source." ); } #[test] - fn create_with_string() { - let detail = "massive".to_string(); - let err = MTTError::new(detail.clone()); + fn with_string() { + let msg = "it went boom".to_string(); + let err = DBError::new(msg.clone()); assert!( - err.to_string() == detail, - "\n\nGot: {}\nWant: {}\n\n", + err.to_string() == msg, + "Got: {} -- Want: {}", err.to_string(), - detail + msg + ); + assert!( + err.source().is_none(), + "Error should initialize with no source." ); } #[test] fn with_source() { - let mut err = MTTError::new("the error"); - let detail = "This is the cause"; - let src = MTTError::new(detail); - err.add_source(src); - assert!( - err.source().unwrap().to_string() == detail, - "/n/nGot: {}\nWant: {}\n\n", - err.source().unwrap().to_string(), - detail - ); - } -} - -#[cfg(test)] -mod generic { - use super::*; - - #[test] - fn create_with_str() { - let detail = "new error"; - let err = Generic::new(detail); - assert!( - err.to_string() == detail, - "\n\nGot: {}\nWant: {}\n\n", - err.to_string(), - detail - ); - assert!( - err.source().is_none(), - "Error source should initialoze to None." - ); - let error: MTTError = err.into(); - assert!( - error.to_string() == detail, - "\n\nGot: {}\nWant: {}\n\n", - error.to_string(), - detail - ); - } - - #[test] - fn create_with_string() { - let detail = "some error".to_string(); - let err = Generic::new(detail.clone()); - assert!( - err.to_string() == detail, - "\n\nGot: {}\nWant: {}\n\n", - err.to_string(), - detail - ); - } - - #[test] - fn with_source() { - let par_detail = "parent error"; - let cld_detail = "child error"; - let par_err = Generic::new(par_detail); - let mut cld_err = Generic::new(cld_detail); - cld_err.add_source(par_err); - assert!( - cld_err.source().unwrap().to_string() == par_detail, - "/n/nGot: {}\nWant: {}\n\n", - cld_err.source().unwrap().to_string(), - par_detail - ); - let error: MTTError = cld_err.into(); - assert!( - error.source().unwrap().to_string() == par_detail, - "/n/nGot: {}\nWant: {}\n\n", - error.source().unwrap().to_string(), - par_detail - ); + let msg = "but this caused the problem"; + let mut par = DBError::new("parent error"); + let src = DBError::new(msg); + par.add_source(src); + let output = par.source(); + assert!(output.is_some(), "Should return source."); + let source = output.unwrap(); + assert!(source.to_string() == msg); } } diff --git a/src/morethantext/mod.rs b/src/morethantext/mod.rs index 9012066..b6c4cc9 100644 --- a/src/morethantext/mod.rs +++ b/src/morethantext/mod.rs @@ -1,120 +1,183 @@ pub mod error; -pub mod fieldtype; use async_std::sync::{Arc, RwLock}; -use error::MTTError; +use error::DBError; +use pest::Parser; use std::collections::HashMap; +enum Ast { + Script, + Command, + Action, + Object, + Name, +} + +#[derive(Parser)] +#[grammar = "morethantext/mttsql.pest"] +struct MTTSQL; + #[derive(Clone)] pub struct MoreThanText { - tables: Arc>>, + databases: Arc>>, } impl MoreThanText { pub async fn new() -> Self { Self { - tables: Arc::new(RwLock::new(HashMap::new())), + databases: Arc::new(RwLock::new(HashMap::new())), } } - pub async fn new_table(&self, tname: S) -> Result - where - S: Into, - { - let mut tables = self.tables.write().await; - let name = tname.into(); - match tables.get(&name) { - Some(_) => Err(MTTError::new(format!("table {} already exists", name))), - None => { - let table = Table::new().await; - tables.insert(name, table.clone()); - Ok(table) + pub async fn execute(&self, script: &str) -> Result<(), DBError> { + match MTTSQL::parse(Rule::file, script) { + Ok(mut commands) => { + let pair = commands.next().unwrap(); + match pair.as_rule() { + Rule::script => Ast::Script, + Rule::command => Ast::Command, + Rule::action => Ast::Action, + Rule::object => Ast::Object, + Rule::name => Ast::Name, + Rule::char | Rule::whitespace | Rule::file | Rule::EOI => unreachable!(), + }; + Ok(()) + } + Err(err) => { + let mut error = DBError::new("script parsing error"); + error.add_source(err); + Err(error) } } } - pub async fn get_table(&self, name: &str) -> Option { - let tables = self.tables.read().await; - match tables.get(name) { - Some(tbl) => Some(tbl.clone()), - None => None, + async fn create_database(&self, name: &str) -> Result<(), DBError> { + let mut databases = self.databases.write().await; + match databases.get(name) { + Some(_) => Err(DBError::new("duplicate database name")), + None => { + let db = Database::new().await; + databases.insert(name.to_string(), db); + Ok(()) + } + } + } + + async fn use_database(&self, name: &str) -> Result<(), DBError> { + let databases = self.databases.read().await; + match databases.get(name) { + Some(_) => Ok(()), + None => Err(DBError::new("database name not found")), } } } -#[derive(Clone)] -pub struct Table; +struct Database; -impl Table { - pub async fn new() -> Self { +impl Database { + async fn new() -> Self { Self {} } - - async fn new_column(&self, _name: &str, _type: &str) {} } #[cfg(test)] -mod database { +mod engine_functions { use super::*; #[async_std::test] - async fn create_table_with_str() { - let db = MoreThanText::new().await; - db.new_table("william").await.unwrap(); + async fn create_database() { + let mtt = MoreThanText::new().await; + mtt.create_database("smith").await.unwrap(); } #[async_std::test] - async fn create_table_with_string() { - let db = MoreThanText::new().await; - db.new_table("marvin".to_string()).await.unwrap(); - } - - #[async_std::test] - async fn table_names_are_unique() -> Result<(), String> { - let db = MoreThanText::new().await; - let name = "alexandar"; - let msg = format!("table {} already exists", name); - db.new_table(name).await.unwrap(); - match db.new_table(name).await { - Ok(_) => Err("Duplicate table names are not allowed.".to_string()), + async fn database_names_must_be_unique() -> Result<(), DBError> { + let mtt = MoreThanText::new().await; + let msg = "duplicate database name"; + mtt.create_database("john").await.unwrap(); + match mtt.create_database("john").await { + Ok(_) => Err(DBError::new("Duplicate names should cause error")), Err(err) => { if err.to_string() == msg { Ok(()) } else { - Err(format!( - "Error message is incorrect: Got: '{}' Want: '{}'", + Err(DBError::new(format!( + "incorrect err message: got: '{}' want: '{}'", err.to_string(), msg - )) + ))) } } } } #[async_std::test] - async fn get_non_existant_table() { - let db = MoreThanText::new().await; - let table = db.get_table("missing").await; - assert!(table.is_none(), "There should be no table."); + async fn use_database() -> Result<(), DBError> { + let mtt = MoreThanText::new().await; + let dbname = "Johnson"; + mtt.create_database(dbname).await.unwrap(); + mtt.use_database(dbname).await.unwrap(); + Ok(()) } #[async_std::test] - async fn get_a_table() { - let db = MoreThanText::new().await; - let name = "here"; - db.new_table(name).await.unwrap(); - let table = db.get_table(name).await; - assert!(table.is_some(), "Table should be found."); + async fn use_missing_database() -> Result<(), DBError> { + let error = "database name not found"; + let mtt = MoreThanText::new().await; + match mtt.use_database("ssmith").await { + Ok(_) => Err(DBError::new("Should raise database missing error")), + Err(err) => { + if err.to_string() == error { + Ok(()) + } else { + Err(DBError::new(format!( + "Incorrect error message: Got '{}' Want '{}'", + err.to_string(), + error + ))) + } + } + } } } #[cfg(test)] -mod table { +mod database_functions { use super::*; #[async_std::test] - async fn add_column() { - let tbl = Table::new().await; - tbl.new_column("fred", "StaticString").await; + async fn new_database() { + Database::new().await; + } +} + +#[cfg(test)] +mod mtt_commands { + use super::*; + + #[async_std::test] + async fn create_database() { + let mtt = MoreThanText::new().await; + mtt.execute("create database fred;").await.unwrap(); + } + + #[async_std::test] + async fn unsuccessful_parse() -> Result<(), DBError> { + let msg = "script parsing error"; + let mtt = MoreThanText::new().await; + match mtt.execute("#$%^&").await { + Ok(_) => Err(DBError::new("Should show a parse failure.")), + Err(err) => { + if err.to_string() == msg { + Ok(()) + } else { + Err(DBError::new(format!( + "Error message is incorrect: Got: '{}' Want: '{}'", + err.to_string(), + msg + ))) + } + } + } } } diff --git a/src/morethantext/mttsql.pest b/src/morethantext/mttsql.pest new file mode 100644 index 0000000..ba00aed --- /dev/null +++ b/src/morethantext/mttsql.pest @@ -0,0 +1,8 @@ +whitespace = _{" " | "\t" | "\r" | "\n"} +action = {"create"} +object = {"database"} +char = _{ ASCII_ALPHANUMERIC | "_" } +name = {char+} +command = {whitespace* ~ action ~ whitespace+ ~ object ~ whitespace+ ~ name ~ whitespace* ~ ";" ~ whitespace*} +script = {command+} +file = _{SOI ~ script ~ EOI} diff --git a/src/morethantext/old-mod2.rs b/src/morethantext/old-mod2.rs new file mode 100644 index 0000000..9012066 --- /dev/null +++ b/src/morethantext/old-mod2.rs @@ -0,0 +1,120 @@ +pub mod error; +pub mod fieldtype; + +use async_std::sync::{Arc, RwLock}; +use error::MTTError; +use std::collections::HashMap; + +#[derive(Clone)] +pub struct MoreThanText { + tables: Arc>>, +} + +impl MoreThanText { + pub async fn new() -> Self { + Self { + tables: Arc::new(RwLock::new(HashMap::new())), + } + } + + pub async fn new_table(&self, tname: S) -> Result + where + S: Into, + { + let mut tables = self.tables.write().await; + let name = tname.into(); + match tables.get(&name) { + Some(_) => Err(MTTError::new(format!("table {} already exists", name))), + None => { + let table = Table::new().await; + tables.insert(name, table.clone()); + Ok(table) + } + } + } + + pub async fn get_table(&self, name: &str) -> Option
{ + let tables = self.tables.read().await; + match tables.get(name) { + Some(tbl) => Some(tbl.clone()), + None => None, + } + } +} + +#[derive(Clone)] +pub struct Table; + +impl Table { + pub async fn new() -> Self { + Self {} + } + + async fn new_column(&self, _name: &str, _type: &str) {} +} + +#[cfg(test)] +mod database { + use super::*; + + #[async_std::test] + async fn create_table_with_str() { + let db = MoreThanText::new().await; + db.new_table("william").await.unwrap(); + } + + #[async_std::test] + async fn create_table_with_string() { + let db = MoreThanText::new().await; + db.new_table("marvin".to_string()).await.unwrap(); + } + + #[async_std::test] + async fn table_names_are_unique() -> Result<(), String> { + let db = MoreThanText::new().await; + let name = "alexandar"; + let msg = format!("table {} already exists", name); + db.new_table(name).await.unwrap(); + match db.new_table(name).await { + Ok(_) => Err("Duplicate table names are not allowed.".to_string()), + Err(err) => { + if err.to_string() == msg { + Ok(()) + } else { + Err(format!( + "Error message is incorrect: Got: '{}' Want: '{}'", + err.to_string(), + msg + )) + } + } + } + } + + #[async_std::test] + async fn get_non_existant_table() { + let db = MoreThanText::new().await; + let table = db.get_table("missing").await; + assert!(table.is_none(), "There should be no table."); + } + + #[async_std::test] + async fn get_a_table() { + let db = MoreThanText::new().await; + let name = "here"; + db.new_table(name).await.unwrap(); + let table = db.get_table(name).await; + assert!(table.is_some(), "Table should be found."); + } +} + +#[cfg(test)] +mod table { + use super::*; + + #[async_std::test] + async fn add_column() { + let tbl = Table::new().await; + tbl.new_column("fred", "StaticString").await; + } +}