diff --git a/Cargo.lock b/Cargo.lock index d37b6db..c857055 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,6 +22,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "ansi_term" version = "0.12.1" @@ -37,6 +52,12 @@ version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +[[package]] +name = "ascii" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" + [[package]] name = "async-stream" version = "0.3.5" @@ -159,6 +180,29 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bson" +version = "1.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de0aa578035b938855a710ba58d43cfb4d435f3619f99236fb35922a574d6cb1" +dependencies = [ + "base64 0.13.1", + "chrono", + "hex", + "lazy_static", + "linked-hash-map", + "rand 0.7.3", + "serde", + "serde_json", + "uuid", +] + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + [[package]] name = "byteorder" version = "1.4.3" @@ -183,6 +227,20 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets", +] + [[package]] name = "clap" version = "2.34.0" @@ -220,6 +278,25 @@ dependencies = [ "winapi", ] +[[package]] +name = "combine" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" +dependencies = [ + "ascii", + "byteorder", + "either", + "memchr", + "unreachable", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + [[package]] name = "cpufeatures" version = "0.2.7" @@ -260,6 +337,17 @@ dependencies = [ "memchr", ] +[[package]] +name = "derive_utils" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "532b4c15dccee12c7044f1fcad956e98410860b22231e44a3b827464797ca7bf" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "digest" version = "0.10.7" @@ -296,6 +384,8 @@ name = "dobby" version = "0.1.0" dependencies = [ "colored", + "juniper", + "juniper_warp", "log", "num", "once_cell", @@ -441,6 +531,21 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.28" @@ -457,6 +562,45 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +[[package]] +name = "futures-enum" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3422d14de7903a52e9dbc10ae05a7e14445ec61890100e098754e120b2bd7b1e" +dependencies = [ + "derive_utils", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + [[package]] name = "futures-sink" version = "0.3.28" @@ -475,9 +619,13 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ + "futures-channel", "futures-core", + "futures-io", + "futures-macro", "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", @@ -493,6 +641,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + [[package]] name = "getrandom" version = "0.2.10" @@ -501,7 +660,17 @@ checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "graphql-parser" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1abd4ce5247dfc04a03ccde70f87a048458c9356c7e41d21ad8c407b3dde6f2" +dependencies = [ + "combine", + "thiserror", ] [[package]] @@ -611,6 +780,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "http" version = "0.2.9" @@ -690,6 +865,29 @@ dependencies = [ "tokio-io-timeout", ] +[[package]] +name = "iana-time-zone" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "idna" version = "0.4.0" @@ -708,6 +906,7 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", + "serde", ] [[package]] @@ -757,6 +956,65 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +[[package]] +name = "js-sys" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "juniper" +version = "0.15.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52adf17d43d0b526eed31fac15d9312941c5c2558ffbfb105811690b96d6e2f1" +dependencies = [ + "async-trait", + "bson", + "chrono", + "fnv", + "futures", + "futures-enum", + "graphql-parser", + "indexmap", + "juniper_codegen", + "serde", + "smartstring", + "static_assertions", + "url", + "uuid", +] + +[[package]] +name = "juniper_codegen" +version = "0.15.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aee97671061ad50301ba077d054d295e01d31a1868fbd07902db651f987e71db" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "juniper_warp" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d167107f6634c92f90daae1a298133377373e935d455042f90efc480fae4a52" +dependencies = [ + "anyhow", + "futures", + "juniper", + "serde", + "serde_json", + "thiserror", + "tokio", + "warp", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -780,6 +1038,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "linux-raw-sys" version = "0.3.8" @@ -827,7 +1091,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys", ] @@ -1174,6 +1438,19 @@ dependencies = [ "nibble_vec", ] +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + [[package]] name = "rand" version = "0.8.5" @@ -1181,8 +1458,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", ] [[package]] @@ -1192,7 +1479,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", ] [[package]] @@ -1201,7 +1497,16 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.10", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", ] [[package]] @@ -1228,7 +1533,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom", + "getrandom 0.2.10", "redox_syscall 0.2.16", "thiserror", ] @@ -1371,6 +1676,7 @@ version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" dependencies = [ + "indexmap", "itoa", "ryu", "serde", @@ -1436,6 +1742,17 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +[[package]] +name = "smartstring" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" +dependencies = [ + "autocfg", + "static_assertions", + "version_check", +] + [[package]] name = "socket2" version = "0.4.9" @@ -1452,6 +1769,12 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "str-buf" version = "1.0.6" @@ -1726,7 +2049,7 @@ dependencies = [ "indexmap", "pin-project", "pin-project-lite", - "rand", + "rand 0.8.5", "slab", "tokio", "tokio-util", @@ -1808,7 +2131,7 @@ dependencies = [ "http", "httparse", "log", - "rand", + "rand 0.8.5", "sha1", "thiserror", "url", @@ -1863,6 +2186,15 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +dependencies = [ + "void", +] + [[package]] name = "unsafe-libyaml" version = "0.2.8" @@ -1892,6 +2224,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" + [[package]] name = "vcpkg" version = "0.2.15" @@ -1910,6 +2248,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + [[package]] name = "want" version = "0.3.0" @@ -1951,12 +2295,72 @@ dependencies = [ "tracing", ] +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.18", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" + [[package]] name = "which" version = "4.4.0" @@ -1999,6 +2403,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-core" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af6041b3f84485c21b57acdc0fee4f4f0c93f426053dc05fa5d6fc262537bbff" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index 9c15114..c83a099 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ thiserror = "1.0" log = "0.4" pretty_env_logger = "0.4" once_cell = "1.15" -num = "0.4.1" +num = "0.4" # TODO: feature-gate this rusqlite = { version = "0.28", features = ["bundled", "column_decltype"] } @@ -32,11 +32,13 @@ tokio = { version= "1.24", features = ["rt-multi-thread", "signal"] } warp = "0.3" tonic = "0.8" prost = "0.11" +juniper = "0.15" rustyline = "10.0" rustyline-derive = "0.7" colored = "2.0" prettytable-rs = "0.10" +juniper_warp = "0.7.0" [dev-dependencies] tempfile = "3.3" diff --git a/openapi.yaml b/openapi.yaml index adf87c9..7931a2c 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -2,12 +2,9 @@ openapi: 3.0.0 info: title: dobby API description: |- - This is an OpenAPI specification for [`dobby`](https://github.com/ly0va/dobby)'s REST API - contact: - email: lyova.potyomkin@gmail.com + This is an OpenAPI specification for `dobby`'s REST API license: name: 'License: MIT' - url: https://github.com/ly0va/dobby/blob/master/LICENSE version: 0.1.0 externalDocs: @@ -15,8 +12,7 @@ externalDocs: url: https://github.com/ly0va/dobby servers: - - url: http://dobby.lyova.xyz - - url: http://do88y.herokuapp.com + - url: http://0.0.0.0:8080 tags: - name: table diff --git a/src/graphql.rs b/src/graphql.rs new file mode 100644 index 0000000..c2318f3 --- /dev/null +++ b/src/graphql.rs @@ -0,0 +1,187 @@ +use juniper::{graphql_object, EmptyMutation, EmptySubscription, RootNode}; +use std::{collections::HashMap, sync::Arc}; +use warp::Filter; + +use crate::core::{ + types::{Query as DbQuery, TypedValue}, + Database, +}; + +struct Context(Arc); +impl juniper::Context for Context {} + +struct Car { + id: i64, + model: String, + price: f64, + owner: i64, +} + +#[graphql_object(context = Context)] +impl Car { + fn id(&self) -> i32 { + self.id as i32 + } + + fn model(&self) -> &str { + &self.model + } + + fn price(&self) -> f64 { + self.price + } + + fn owner(&self, context: &Context) -> Option { + context + .0 + .execute(DbQuery::Select { + from: "people".to_string(), + columns: Default::default(), + conditions: [("id".to_string(), TypedValue::Int(self.owner))] + .into_iter() + .collect(), + }) + .map(|result| { + result + .into_iter() + .map(|row| Person { + id: row.get("id").unwrap().to_string().parse().unwrap(), + name: row.get("name").unwrap().to_string().parse().unwrap(), + age: row.get("age").unwrap().to_string().parse().unwrap(), + }) + .next() + }) + .unwrap_or_default() + } +} + +struct Person { + id: i64, + name: String, + age: i64, +} + +#[graphql_object(context = Context)] +impl Person { + fn id(&self) -> i32 { + self.id as i32 + } + + fn name(&self) -> &str { + &self.name + } + + fn age(&self) -> i32 { + self.age as i32 + } +} + +struct Query; + +impl Query { + fn get_cars(conditions: HashMap, context: &Context) -> Vec { + context + .0 + .execute(DbQuery::Select { + from: "cars".to_string(), + columns: Default::default(), + conditions, + }) + .map(|result| { + result + .into_iter() + .map(|row| Car { + id: row.get("id").unwrap().to_string().parse().unwrap(), + model: row.get("model").unwrap().to_string().parse().unwrap(), + price: row.get("price").unwrap().to_string().parse().unwrap(), + owner: row.get("owner").unwrap().to_string().parse().unwrap(), + }) + .collect() + }) + .unwrap_or_default() + } + + fn get_people(conditions: HashMap, context: &Context) -> Vec { + context + .0 + .execute(DbQuery::Select { + from: "people".to_string(), + columns: Default::default(), + conditions, + }) + .map(|result| { + result + .into_iter() + .map(|row| Person { + id: row.get("id").unwrap().to_string().parse().unwrap(), + name: row.get("name").unwrap().to_string().parse().unwrap(), + age: row.get("age").unwrap().to_string().parse().unwrap(), + }) + .collect() + }) + .unwrap_or_default() + } +} + +#[graphql_object(context = Context)] +impl Query { + fn people(context: &Context) -> Vec { + Self::get_people(Default::default(), context) + } + + fn cars(context: &Context) -> Vec { + Self::get_cars(Default::default(), context) + } + + fn car(id: i32, context: &Context) -> Option { + Self::get_cars( + [("id".to_string(), TypedValue::Int(id as i64))] + .into_iter() + .collect(), + context, + ) + .into_iter() + .next() + } + + fn person(id: i32, context: &Context) -> Option { + Self::get_people( + [("id".to_string(), TypedValue::Int(id as i64))] + .into_iter() + .collect(), + context, + ) + .into_iter() + .next() + } +} + +type Schema = RootNode<'static, Query, EmptyMutation, EmptySubscription>; + +fn schema() -> Schema { + Schema::new(Query, EmptyMutation::new(), EmptySubscription::new()) +} + +pub fn graphql( + db: Arc, +) -> impl Filter + Clone { + let context = warp::any().map(move || Context(Arc::clone(&db))); + + let query = warp::post() + .and(warp::path("graphql")) + .and(warp::path::end()) + .and(juniper_warp::make_graphql_filter(schema(), context.boxed())); + + let playground = warp::get() + .and(warp::path("playground")) + .and(juniper_warp::playground_filter("/graphql", None)); + + let graphiql = warp::get() + .and(warp::path("graphiql")) + .and(juniper_warp::graphiql_filter("/graphql", None)); + + query + .or(playground) + .or(graphiql) + .with(warp::log("api::graphql")) +} diff --git a/src/lib.rs b/src/lib.rs index 18dd2bc..070c757 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,5 @@ pub mod cli; pub mod core; +pub mod graphql; pub mod grpc; pub mod rest; diff --git a/src/rest.rs b/src/rest.rs index a38e646..f0c5fed 100644 --- a/src/rest.rs +++ b/src/rest.rs @@ -130,7 +130,8 @@ pub async fn serve(db_itself: Arc, address: impl Into) .and(warp::path::end()) .map(|| warp::reply::html(include_str!("../static/index.html"))); - let routes = select + let routes = crate::graphql::graphql(Arc::clone(&db_itself)) + .or(select) .or(insert) .or(update) .or(delete)