From 747b69819132d80fe2e0779b46baa5873e2be5d8 Mon Sep 17 00:00:00 2001 From: Garrit Franke Date: Fri, 10 Sep 2021 22:53:03 +0200 Subject: [PATCH] feat: persistence --- .env | 1 + Cargo.lock | 46 +++++++++++ Cargo.toml | 2 + db.sqlite | Bin 0 -> 16384 bytes diesel.toml | 5 ++ migrations/.gitkeep | 0 .../2021-09-10-191958_create_users/down.sql | 1 + .../2021-09-10-191958_create_users/up.sql | 4 + src/main.rs | 76 +++++++++++++++--- src/models.rs | 14 ++++ src/schema.rs | 6 ++ 11 files changed, 146 insertions(+), 9 deletions(-) create mode 100644 .env create mode 100644 db.sqlite create mode 100644 diesel.toml create mode 100644 migrations/.gitkeep create mode 100644 migrations/2021-09-10-191958_create_users/down.sql create mode 100644 migrations/2021-09-10-191958_create_users/up.sql create mode 100644 src/models.rs create mode 100644 src/schema.rs diff --git a/.env b/.env new file mode 100644 index 0000000..27d7e7e --- /dev/null +++ b/.env @@ -0,0 +1 @@ +DATABASE_URL=db.sqlite diff --git a/Cargo.lock b/Cargo.lock index bdbf591..00a29e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,6 +4,8 @@ name = "astrofarm" version = "0.1.0" dependencies = [ + "diesel", + "dotenv", "gempress", ] @@ -19,6 +21,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + [[package]] name = "cc" version = "1.0.70" @@ -31,6 +39,34 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "diesel" +version = "1.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bba51ca66f57261fd17cadf8b73e4775cc307d0521d855de3f5de91a8f074e0e" +dependencies = [ + "byteorder", + "diesel_derives", + "libsqlite3-sys", +] + +[[package]] +name = "diesel_derives" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + [[package]] name = "foreign-types" version = "0.3.2" @@ -82,6 +118,16 @@ version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21" +[[package]] +name = "libsqlite3-sys" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290b64917f8b0cb885d9de0f9959fe1f775d7fa12f1da2db9001c1c8ab60f89d" +dependencies = [ + "pkg-config", + "vcpkg", +] + [[package]] name = "matches" version = "0.1.9" diff --git a/Cargo.toml b/Cargo.toml index 21d8743..c282f80 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,3 +8,5 @@ edition = "2018" [dependencies] gempress = { path = "lib/gempress" } +diesel = { version = "1.4.4", features = ["sqlite"] } +dotenv = "0.15.0" diff --git a/db.sqlite b/db.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..49085cbe2267fb7f0b8bce4fe25771fc69abfd05 GIT binary patch literal 16384 zcmeI%F>ljA6bJCTI5-d~JrIM%_6CMnqF^VDL^|~d*An4`;y6g1EJNJZQWA^UsaVTb z;iIrHG6EAL6JqShB{&h42s2dwr#nBN?_@v!h=S5pnN*?yFKY2(NlFq{bvF7 zhn{y&FPTP@m|jS~^F;dViK=~mz$=!N{Oz6PrNVHO#92HJvsb6_Bnl_V$t=o~bee6R zDP1aR^E#@Z>HE;nebo=b^%8qf zGOZKISu!2PZ?e~8{k|SX^E_RS!_8%d?&di|KWf((kK5uUpNlU{Hv|MA009U<00Izz z00bZa0SG_<0{@-BU2fRThSPAJw(GcUx7~WU7;QW4ZP%fOv%AyWZS7R`eR1)f>4ty+ z1Rwwb2tWV=5P$##AOHafK;TLU+%oJNmp=(C{{L6R2PQ7W5AjWW6`#aMJw!kN0uX=z q1Rwwb2tWV=5P$##An*?gm=%NF-cM80Eb_G?my2u^xm0BSEB^#al&PKo literal 0 HcmV?d00001 diff --git a/diesel.toml b/diesel.toml new file mode 100644 index 0000000..92267c8 --- /dev/null +++ b/diesel.toml @@ -0,0 +1,5 @@ +# For documentation on how to configure this file, +# see diesel.rs/guides/configuring-diesel-cli + +[print_schema] +file = "src/schema.rs" diff --git a/migrations/.gitkeep b/migrations/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/migrations/2021-09-10-191958_create_users/down.sql b/migrations/2021-09-10-191958_create_users/down.sql new file mode 100644 index 0000000..7fa478c --- /dev/null +++ b/migrations/2021-09-10-191958_create_users/down.sql @@ -0,0 +1 @@ +drop table users; diff --git a/migrations/2021-09-10-191958_create_users/up.sql b/migrations/2021-09-10-191958_create_users/up.sql new file mode 100644 index 0000000..1c89c85 --- /dev/null +++ b/migrations/2021-09-10-191958_create_users/up.sql @@ -0,0 +1,4 @@ +CREATE TABLE users ( + id INTEGER PRIMARY KEY NOT NULL, + name VARCHAR NOT NULL +); diff --git a/src/main.rs b/src/main.rs index 0cd4fc3..1babba6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,17 +1,30 @@ extern crate gempress; +extern crate dotenv; +#[macro_use] extern crate diesel; + +use std::path::PathBuf; +use std::env; use gempress::Gempress; use gempress::error::GempressResult; use gempress::gemini; use gempress::gemini::StatusCode; -use std::path::PathBuf; -use std::hash::{Hash, Hasher}; -use std::collections::hash_map::DefaultHasher; -fn calculate_hash(t: &T) -> u64 { - let mut s = DefaultHasher::new(); - t.hash(&mut s); - s.finish() +use diesel::prelude::*; +use diesel::sqlite::SqliteConnection; + +use self::models::*; + +pub mod models; +pub mod schema; + +pub fn establish_connection() -> SqliteConnection { + dotenv::dotenv().ok(); + + let database_url = env::var("DATABASE_URL") + .expect("DATABASE_URL must be set"); + SqliteConnection::establish(&database_url) + .expect(&format!("Error connecting to {}", database_url)) } fn index_handler(req: Box, mut res: Box) -> GempressResult<()>{ @@ -20,7 +33,49 @@ fn index_handler(req: Box, mut res: Box) -> G Hello, {} "#, "user"); - println!("Index handler"); + res.status(StatusCode::Success)?.send(response.as_bytes())?; + Ok(()) +} + +fn add_user_handler(req: Box, mut res: Box) -> GempressResult<()>{ + use self::schema::users::dsl::*; + + let conn = establish_connection(); + + let new_user = NewUser { + name: "Foo".into(), + }; + + diesel::insert_into(users).values(new_user).execute(&conn); + + let user: User = users + .order(id.desc()) + .first(&conn) + .expect("Error loading posts"); + + let response = format!(r#" + # User inserted + User "{}" created. ID: {} + "#, user.name, user.id); + + res.status(StatusCode::Success)?.send(response.as_bytes())?; + Ok(()) +} + +fn show_users_handler(req: Box, mut res: Box) -> GempressResult<()>{ + use self::schema::users::dsl::*; + + let conn = establish_connection(); + + let results = users + .load::(&conn) + .expect("Error loading posts"); + + let mut response = "# Users\n\n".to_string(); + + for user in results { + response += &format!("{}: {}\n", user.id, user.name); + }; res.status(StatusCode::Success)?.send(response.as_bytes())?; Ok(()) @@ -30,9 +85,12 @@ fn main() { // Run make_cert.sh to generate a certificate let config = gempress::Config::new(PathBuf::from("cert.pem"), PathBuf::from("key.pem")); + let conn = establish_connection(); + let mut app = Gempress::new(config); - app.on("/", &index_handler); + app.on("/", &show_users_handler); + app.on("/add_user", &add_user_handler); app.listen(1965, || { println!("Listening on port 1965"); diff --git a/src/models.rs b/src/models.rs new file mode 100644 index 0000000..f6edcd1 --- /dev/null +++ b/src/models.rs @@ -0,0 +1,14 @@ +use diesel::{Queryable, Insertable}; +use super::schema::users; + +#[derive(Queryable)] +pub struct User { + pub id: i32, + pub name: String, +} + +#[derive(Insertable)] +#[table_name="users"] +pub struct NewUser { + pub name: String, +} diff --git a/src/schema.rs b/src/schema.rs new file mode 100644 index 0000000..3502adb --- /dev/null +++ b/src/schema.rs @@ -0,0 +1,6 @@ +table! { + users (id) { + id -> Integer, + name -> Text, + } +}