diff --git a/Cargo.lock b/Cargo.lock index 637995f..eb4bf0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,8 +14,8 @@ dependencies = [ "futures-sink", "log", "pin-project 0.4.28", - "tokio", - "tokio-util", + "tokio 0.2.25", + "tokio-util 0.3.1", ] [[package]] @@ -74,7 +74,7 @@ dependencies = [ "mime", "percent-encoding", "pin-project 1.0.7", - "rand", + "rand 0.7.3", "regex", "serde", "serde_json", @@ -119,7 +119,7 @@ dependencies = [ "futures-channel", "futures-util", "smallvec", - "tokio", + "tokio 0.2.25", ] [[package]] @@ -135,11 +135,11 @@ dependencies = [ "futures-channel", "futures-util", "log", - "mio", + "mio 0.6.23", "mio-uds", "num_cpus", "slab", - "socket2", + "socket2 0.3.19", ] [[package]] @@ -163,7 +163,7 @@ dependencies = [ "actix-server", "actix-service", "log", - "socket2", + "socket2 0.3.19", ] [[package]] @@ -246,7 +246,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "socket2", + "socket2 0.3.19", "time", "tinyvec", "url", @@ -313,7 +313,7 @@ dependencies = [ "log", "mime", "percent-encoding", - "rand", + "rand 0.7.3", "serde", "serde_json", "serde_urlencoded", @@ -464,6 +464,16 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "crypto-mac" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4857fd85a0c34b3c3297875b747c1e02e06b6a0ea32dd892d8192b9ce0813ea6" +dependencies = [ + "generic-array", + "subtle", +] + [[package]] name = "derive_more" version = "0.99.14" @@ -486,6 +496,7 @@ dependencies = [ "byteorder", "diesel_derives", "pq-sys", + "r2d2", ] [[package]] @@ -547,6 +558,12 @@ dependencies = [ "syn", ] +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + [[package]] name = "flate2" version = "1.0.20" @@ -599,6 +616,7 @@ checksum = "0e7e43a803dae2fa37c1f6a8fe121e1f7bf9548b4dfc0522a42f34145dadfc27" dependencies = [ "futures-channel", "futures-core", + "futures-executor", "futures-io", "futures-sink", "futures-task", @@ -621,6 +639,17 @@ version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1" +[[package]] +name = "futures-executor" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "badaa6a909fac9e7236d0620a2f57f7664640c56575b71a7552fbd68deafab79" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + [[package]] name = "futures-io" version = "0.3.15" @@ -700,7 +729,18 @@ checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ "cfg-if 1.0.0", "libc", - "wasi", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", ] [[package]] @@ -717,8 +757,8 @@ dependencies = [ "http", "indexmap", "slab", - "tokio", - "tokio-util", + "tokio 0.2.25", + "tokio-util 0.3.1", "tracing", "tracing-futures", ] @@ -747,6 +787,16 @@ dependencies = [ "libc", ] +[[package]] +name = "hmac" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" +dependencies = [ + "crypto-mac", + "digest", +] + [[package]] name = "hostname" version = "0.3.1" @@ -820,7 +870,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7" dependencies = [ - "socket2", + "socket2 0.3.19", "widestring", "winapi 0.3.9", "winreg", @@ -839,6 +889,8 @@ dependencies = [ "actix-web", "diesel", "dotenv", + "r2d2", + "r2d2_postgres", "serde", "serde_json", ] @@ -916,6 +968,17 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" +[[package]] +name = "md-5" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5a279bb9607f9f53c22d496eade00d138d1bdcccd07d74650387cf94942a15" +dependencies = [ + "block-buffer", + "digest", + "opaque-debug", +] + [[package]] name = "memchr" version = "2.4.0" @@ -951,12 +1014,25 @@ dependencies = [ "kernel32-sys", "libc", "log", - "miow", + "miow 0.2.2", "net2", "slab", "winapi 0.2.8", ] +[[package]] +name = "mio" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16" +dependencies = [ + "libc", + "log", + "miow 0.3.7", + "ntapi", + "winapi 0.3.9", +] + [[package]] name = "mio-uds" version = "0.6.8" @@ -965,7 +1041,7 @@ checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" dependencies = [ "iovec", "libc", - "mio", + "mio 0.6.23", ] [[package]] @@ -980,6 +1056,15 @@ dependencies = [ "ws2_32-sys", ] +[[package]] +name = "miow" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "net2" version = "0.2.37" @@ -991,6 +1076,15 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "ntapi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "num_cpus" version = "1.13.0" @@ -1038,6 +1132,24 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project" version = "0.4.28" @@ -1096,6 +1208,49 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "postgres" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7871ee579860d8183f542e387b176a25f2656b9fb5211e045397f745a68d1c2" +dependencies = [ + "bytes 1.0.1", + "fallible-iterator", + "futures", + "log", + "tokio 1.7.1", + "tokio-postgres", +] + +[[package]] +name = "postgres-protocol" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff3e0f70d32e20923cabf2df02913be7c1842d4c772db8065c00fcfdd1d1bff3" +dependencies = [ + "base64", + "byteorder", + "bytes 1.0.1", + "fallible-iterator", + "hmac", + "md-5", + "memchr", + "rand 0.8.4", + "sha2", + "stringprep", +] + +[[package]] +name = "postgres-types" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "430f4131e1b7657b0cd9a2b0c3408d77c9a43a042d300b8c77f981dffcc43a2f" +dependencies = [ + "bytes 1.0.1", + "fallible-iterator", + "postgres-protocol", +] + [[package]] name = "ppv-lite86" version = "0.2.10" @@ -1147,17 +1302,50 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r2d2" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "545c5bc2b880973c9c10e4067418407a0ccaa3091781d1671d46eb35107cb26f" +dependencies = [ + "log", + "parking_lot", + "scheduled-thread-pool", +] + +[[package]] +name = "r2d2_postgres" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7665d196d831b5c4f9ac49b3e2518e99555fe1941ccd103480817108c7c2f6e" +dependencies = [ + "postgres", + "r2d2", +] + [[package]] name = "rand" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom", + "getrandom 0.1.16", "libc", - "rand_chacha", - "rand_core", - "rand_hc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", +] + +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", ] [[package]] @@ -1167,7 +1355,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", ] [[package]] @@ -1176,7 +1374,16 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom", + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.3", ] [[package]] @@ -1185,7 +1392,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core 0.6.3", ] [[package]] @@ -1239,6 +1455,15 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +[[package]] +name = "scheduled-thread-pool" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6f74fd1204073fa02d5d5d68bec8021be4c38690b61264b2fdb48083d0e7d7" +dependencies = [ + "parking_lot", +] + [[package]] name = "scopeguard" version = "1.1.0" @@ -1322,6 +1547,19 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" +[[package]] +name = "sha2" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12" +dependencies = [ + "block-buffer", + "cfg-if 1.0.0", + "cpufeatures", + "digest", + "opaque-debug", +] + [[package]] name = "signal-hook-registry" version = "1.4.0" @@ -1331,6 +1569,12 @@ dependencies = [ "libc", ] +[[package]] +name = "siphasher" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbce6d4507c7e4a3962091436e56e95290cb71fa302d0d270e32130b75fbff27" + [[package]] name = "slab" version = "0.4.3" @@ -1354,6 +1598,16 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "socket2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2" +dependencies = [ + "libc", + "winapi 0.3.9", +] + [[package]] name = "standback" version = "0.2.17" @@ -1412,6 +1666,22 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" +[[package]] +name = "stringprep" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "subtle" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" + [[package]] name = "syn" version = "1.0.72" @@ -1517,7 +1787,7 @@ dependencies = [ "lazy_static", "libc", "memchr", - "mio", + "mio 0.6.23", "mio-uds", "pin-project-lite 0.1.12", "signal-hook-registry", @@ -1525,6 +1795,44 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "tokio" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fb2ed024293bb19f7a5dc54fe83bf86532a44c12a2bb8ba40d64a4509395ca2" +dependencies = [ + "autocfg", + "bytes 1.0.1", + "libc", + "memchr", + "mio 0.7.13", + "pin-project-lite 0.2.6", + "winapi 0.3.9", +] + +[[package]] +name = "tokio-postgres" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d2b1383c7e4fb9a09e292c7c6afb7da54418d53b045f1c1fac7a911411a2b8b" +dependencies = [ + "async-trait", + "byteorder", + "bytes 1.0.1", + "fallible-iterator", + "futures", + "log", + "parking_lot", + "percent-encoding", + "phf", + "pin-project-lite 0.2.6", + "postgres-protocol", + "postgres-types", + "socket2 0.4.0", + "tokio 1.7.1", + "tokio-util 0.6.7", +] + [[package]] name = "tokio-util" version = "0.3.1" @@ -1536,7 +1844,21 @@ dependencies = [ "futures-sink", "log", "pin-project-lite 0.1.12", - "tokio", + "tokio 0.2.25", +] + +[[package]] +name = "tokio-util" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592" +dependencies = [ + "bytes 1.0.1", + "futures-core", + "futures-sink", + "log", + "pin-project-lite 0.2.6", + "tokio 1.7.1", ] [[package]] @@ -1583,10 +1905,10 @@ dependencies = [ "idna", "lazy_static", "log", - "rand", + "rand 0.7.3", "smallvec", "thiserror", - "tokio", + "tokio 0.2.25", "url", ] @@ -1605,7 +1927,7 @@ dependencies = [ "resolv-conf", "smallvec", "thiserror", - "tokio", + "tokio 0.2.25", "trust-dns-proto", ] @@ -1675,6 +1997,12 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + [[package]] name = "wasm-bindgen" version = "0.2.74" diff --git a/Cargo.toml b/Cargo.toml index 5265bca..1cf26e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,5 +10,7 @@ edition = "2018" actix-web = "3" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.64" -diesel = { version = "1.4.4", features = ["postgres"] } -dotenv = "0.15.0" \ No newline at end of file +diesel = { version = "1.4.4", features = ["postgres", "r2d2"] } +dotenv = "0.15.0" +r2d2 = "0.8.9" +r2d2_postgres = "0.18.0" \ No newline at end of file diff --git a/migrations/2021-07-02-125712_hugo/down.sql b/migrations/2021-07-02-125712_hugo/down.sql new file mode 100644 index 0000000..cc9f0b9 --- /dev/null +++ b/migrations/2021-07-02-125712_hugo/down.sql @@ -0,0 +1,3 @@ +-- This file should undo anything in `up.sql` + +DROP TABLE person; \ No newline at end of file diff --git a/migrations/2021-07-02-125712_hugo/up.sql b/migrations/2021-07-02-125712_hugo/up.sql new file mode 100644 index 0000000..6f5eb59 --- /dev/null +++ b/migrations/2021-07-02-125712_hugo/up.sql @@ -0,0 +1,7 @@ +-- Your SQL goes here + +CREATE TABLE person ( + id CHAR(4) NOT NULL PRIMARY KEY , + name VARCHAR(45) NOT NULL, + age INT NOT NULL DEFAULT 0 +); \ No newline at end of file diff --git a/src/actions.rs b/src/actions.rs new file mode 100644 index 0000000..ad65747 --- /dev/null +++ b/src/actions.rs @@ -0,0 +1,32 @@ +use crate::models::{NewPost, Person, Post}; + +use crate::schema::*; +use diesel::prelude::*; + +pub fn insert_post(con: &PgConnection, new_post: &Post) -> QueryResult { + let new_post = NewPost { + author: &new_post.author, + title: &new_post.title, + body: &new_post.body, + }; + + diesel::insert_into(posts::table) + .values(&new_post) + .get_result::(con) +} + +pub fn update_person(con: &PgConnection, update_person: &Person) -> QueryResult { + use crate::schema::person::dsl::*; + diesel::update(person.find("hugo".to_string())) + .set((name.eq(&update_person.name), age.eq(update_person.age))) + .get_result(con) +} + +pub fn find_person_by_id(con: &PgConnection, person_id: &str) -> QueryResult> { + use crate::schema::person::dsl::*; + let user: Option = person + .filter(id.eq(person_id)) + .first::(con) + .optional()?; + Ok(user) +} diff --git a/src/main.rs b/src/main.rs index b878db6..61849e9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,25 +2,52 @@ extern crate diesel; extern crate dotenv; +use std::env; +use std::error::Error; + +use crate::models::{Person, Post}; +use actix_web::web::Data; +use actix_web::{get, post, web, App, Either, HttpResponse, HttpServer, Responder}; +use diesel::prelude::*; +use diesel::r2d2::{ConnectionManager, Pool}; +use dotenv::dotenv; +use std::fmt::Debug; + +mod actions; mod models; mod schema; -use std::error::Error; -use std::sync::Mutex; +type DbPool = Pool>; +type WebResult = Result; -use diesel::prelude::*; -use dotenv::dotenv; -use std::env; +#[get("/post/{id}")] +async fn get_post(web::Path(path_id): web::Path) -> impl Responder { + use self::schema::posts::dsl::*; -use crate::models::{Person, Post}; -use actix_web::{get, post, web, App, Either, HttpResponse, HttpServer, Responder}; + let result = web::block::<_, Vec, _>(move || { + let connection = establish_connection(); -struct AppState { - posts: Mutex>, - hugo: Mutex, + posts + .filter(id.eq(path_id as i32)) + .load::(&connection) + }) + .await + .map_err(|e| { + eprintln!("{:?}", e); + HttpResponse::InternalServerError().finish() + }) + .map(|mut vec| { + if vec.len() > 0 { + Either::A(HttpResponse::Ok().json(vec.remove(0))) + } else { + Either::B(HttpResponse::NotFound().finish()) + } + }); + + result } -#[get("post")] +#[get("/post")] async fn get_posts() -> impl Responder { use crate::schema::posts::dsl::*; @@ -38,72 +65,57 @@ async fn get_posts() -> impl Responder { results } -#[get("/post/{id}")] -async fn get_post( - web::Path(id): web::Path, - data: web::Data, -) -> Either { - let posts = data.posts.lock().unwrap(); - - match posts.get(id) { - None => Either::A(HttpResponse::NotFound()), - Some(post) => Either::B(post.clone()), - } -} - #[post("/post")] -async fn post_post(mut post: web::Json, data: web::Data) -> impl Responder { - let mut posts = data.posts.lock().unwrap(); - post.id = posts.len() as i32; - posts.push(post.clone()); - post +async fn post_post(post: web::Json, data: Data) -> WebResult { + let con = data.get().expect("could not get connection from pool"); + + let p = web::block(move || actions::insert_post(&con, &post)) + .await + .map_err(internal_server_error)?; + + Ok(HttpResponse::Ok().json(p)) } #[get("/hugo")] -async fn hugo(data: web::Data) -> impl Responder { - let hugo_person = data.hugo.lock().unwrap(); +async fn get_hugo(pool: Data) -> WebResult { + let con = pool.get().expect("Could not get db connection from pool"); - HttpResponse::Ok() - .content_type("application/json") - .body(serde_json::to_string(&*hugo_person).unwrap()) + let hugo = web::block(move || actions::find_person_by_id(&con, "hugo")) + .await + .map_err(internal_server_error)?; + + match hugo { + Some(p) => Ok(HttpResponse::Ok().json(p)), + None => Ok(HttpResponse::NotFound() + .body("Hugo was not found here. Consider creating him with the id 'hugo'.")), + } } #[post("/hugo")] -async fn hugo_post(new_hugo: web::Json, data: web::Data) -> impl Responder { - let mut hugo_person = data.hugo.lock().unwrap(); - *hugo_person = new_hugo.clone(); - new_hugo +async fn hugo_post(new_hugo: web::Json, pool: Data) -> WebResult { + let con = pool.get().expect("Could not get db connection from pool"); + + let person = web::block(move || actions::update_person(&con, &new_hugo)) + .await + .map_err(internal_server_error)?; + Ok(HttpResponse::Ok().json(person)) } #[actix_web::main] async fn main() -> Result<(), Box> { - /*let pool = PgPoolOptions::new() - .max_connections(5) - .connect("postgres://postgres:karl@localhost/karlheinz") - .await?;*/ + dotenv().ok(); - let posts = vec![Post { - id: 0, - author: "Hugo Boss".to_string(), - title: "I like winning".to_string(), - body: "I really like winning. That's why I always win at everything".to_string(), - }]; + let url = std::env::var("DATABASE_URL").expect("Did not find Database URL"); + let manager = diesel::r2d2::ConnectionManager::::new(url); - let data = web::Data::new(AppState { - posts: Mutex::new(posts), - hugo: Mutex::new(Person { - name: "Hugo Boss".to_string(), - age: 40, - }), - }); + let pool: DbPool = r2d2::Pool::new(manager).unwrap(); println!("Started Server..."); HttpServer::new(move || { App::new() - // .data(pool.clone()) - .app_data(data.clone()) + .data(pool.clone()) .service(hugo_post) - .service(hugo) + .service(get_hugo) .service(get_post) .service(post_post) .service(get_posts) @@ -114,8 +126,12 @@ async fn main() -> Result<(), Box> { Ok(()) } +pub fn internal_server_error(err: impl Debug) -> HttpResponse { + eprintln!("{:?}", err); + HttpResponse::InternalServerError().finish() +} + pub fn establish_connection() -> PgConnection { - dotenv().ok(); let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); PgConnection::establish(&database_url).expect(&format!("Error connecting to {}", database_url)) } diff --git a/src/models.rs b/src/models.rs index db95b44..c4e900d 100644 --- a/src/models.rs +++ b/src/models.rs @@ -1,3 +1,4 @@ +use super::schema::posts; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Queryable, Clone)] @@ -9,8 +10,18 @@ pub struct Post { pub body: String, } -#[derive(Serialize, Deserialize, Clone)] +#[derive(Insertable)] +#[table_name = "posts"] +pub struct NewPost<'a> { + pub author: &'a str, + pub title: &'a str, + pub body: &'a str, +} + +#[derive(Serialize, Deserialize, Clone, Queryable)] pub struct Person { + #[serde(default)] + pub id: String, pub name: String, pub age: i32, } @@ -24,12 +35,11 @@ macro_rules! impl_responder { fn respond_to(self, _req: &actix_web::HttpRequest) -> Self::Future { let body = serde_json::to_string(&self).unwrap(); - std::future::ready(Ok(actix_web::HttpResponse::Ok() - .content_type("application/json") - .body(body))) + std::future::ready(Ok(actix_web::HttpResponse::Ok().json(body))) } } }; } + impl_responder!(for Person); impl_responder!(for Post); diff --git a/src/schema.rs b/src/schema.rs index 634dc43..404705a 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -1,3 +1,11 @@ +table! { + person (id) { + id -> Bpchar, + name -> Varchar, + age -> Int4, + } +} + table! { posts (id) { id -> Int4, @@ -6,3 +14,8 @@ table! { body -> Varchar, } } + +allow_tables_to_appear_in_same_query!( + person, + posts, +);