From e4beab93426b490be5ac2e8e9318559e611a9ec6 Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Wed, 01 Sep 2021 00:03:10 +0100 Subject: [PATCH] introduce diesel for state management --- .env | 1 + .gitignore | 1 + Cargo.lock | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + diesel.toml | 5 +++++ chartered-db/Cargo.toml | 11 +++++++++++ chartered-db/README.md | 3 +++ chartered-web/Cargo.toml | 2 ++ migrations/.gitkeep | 0 chartered-db/src/lib.rs | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ chartered-db/src/schema.rs | 23 +++++++++++++++++++++++ chartered-web/src/main.rs | 6 +++++- migrations/2021-08-31-214501_create_crates_table/down.sql | 2 ++ migrations/2021-08-31-214501_create_crates_table/up.sql | 17 +++++++++++++++++ 14 files changed, 220 insertions(+), 1 deletion(-) diff --git a/.env b/.env new file mode 100644 index 0000000..5f2cbfe 100644 --- /dev/null +++ a/.env @@ -1,0 +1,1 @@ +DATABASE_URL=chartered.db diff --git a/.gitignore b/.gitignore index c403c34..12fad47 100644 --- a/.gitignore +++ a/.gitignore @@ -1,2 +1,3 @@ /target .idea/ +/chartered.db diff --git a/Cargo.lock b/Cargo.lock index b0fd9d7..be6c069 100644 --- a/Cargo.lock +++ a/Cargo.lock @@ -183,8 +183,22 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] +name = "chartered-db" +version = "0.1.0" +dependencies = [ + "diesel", + "dotenv", + "tokio", +] + +[[package]] name = "chartered-fs" version = "0.1.0" +dependencies = [ + "async-trait", + "tokio", + "uuid", +] [[package]] name = "chartered-git" @@ -214,6 +228,7 @@ version = "0.1.0" dependencies = [ "axum", + "chartered-db", "futures", "tokio", "tower", @@ -315,6 +330,29 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" + +[[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", + "r2d2", +] + +[[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 = "digest" @@ -344,6 +382,12 @@ "redox_users", "winapi", ] + +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" [[package]] name = "env_logger" @@ -648,6 +692,16 @@ "libc", "pkg-config", "walkdir", +] + +[[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]] @@ -906,6 +960,17 @@ checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" 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]] @@ -997,6 +1062,15 @@ checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ "winapi-util", +] + +[[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]] @@ -1382,6 +1456,15 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom", +] [[package]] name = "vcpkg" diff --git a/Cargo.toml b/Cargo.toml index 11a3cbb..0add9bb 100644 --- a/Cargo.toml +++ a/Cargo.toml @@ -1,6 +1,7 @@ [workspace] members = [ "chartered-git", "chartered-web", "chartered-fs", + "chartered-db", ] diff --git a/diesel.toml b/diesel.toml new file mode 100644 index 0000000..2236288 100644 --- /dev/null +++ a/diesel.toml @@ -1,0 +1,5 @@ +# For documentation on how to configure this file, +# see diesel.rs/guides/configuring-diesel-cli + +[print_schema] +file = "chartered-db/src/schema.rs" diff --git a/chartered-db/Cargo.toml b/chartered-db/Cargo.toml new file mode 100644 index 0000000..b6a463c 100644 --- /dev/null +++ a/chartered-db/Cargo.toml @@ -1,0 +1,11 @@ +[package] +name = "chartered-db" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +diesel = { version = "1", features = ["sqlite", "r2d2"] } +tokio = { version = "1" } +dotenv = "0.15" diff --git a/chartered-db/README.md b/chartered-db/README.md new file mode 100644 index 0000000..62f9c41 100644 --- /dev/null +++ a/chartered-db/README.md @@ -1,0 +1,3 @@ +# chartered-db (library) + +Defines the database schema and corresponding queries for chartered. diff --git a/chartered-web/Cargo.toml b/chartered-web/Cargo.toml index d1ac7f5..34b4f34 100644 --- a/chartered-web/Cargo.toml +++ a/chartered-web/Cargo.toml @@ -6,6 +6,8 @@ # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +chartered-db = { path = "../chartered-db" } + axum = "0.2" futures = "0.3" tokio = { version = "1", features = ["full"] } diff --git a/migrations/.gitkeep b/migrations/.gitkeep new file mode 100644 index 0000000..e69de29 100644 --- /dev/null +++ a/migrations/.gitkeep diff --git a/chartered-db/src/lib.rs b/chartered-db/src/lib.rs new file mode 100644 index 0000000..ca673ad 100644 --- /dev/null +++ a/chartered-db/src/lib.rs @@ -1,0 +1,66 @@ +#[macro_use] +extern crate diesel; + +pub mod schema; + +use std::sync::Arc; + +use self::diesel::prelude::*; +use diesel::{ + r2d2::{ConnectionManager, Pool}, + Associations, Identifiable, Queryable, +}; + +use schema::crate_versions; +use schema::crates; + +pub fn init() -> Arc>> { + Arc::new(Pool::new(ConnectionManager::new("chartered.db")).unwrap()) +} + +#[derive(Identifiable, Queryable, PartialEq, Debug)] +pub struct Crate { + id: i32, + name: String, +} + +#[derive(Identifiable, Queryable, Associations, PartialEq, Debug)] +#[belongs_to(Crate)] +pub struct CrateVersion { + id: i32, + crate_id: i32, + version: String, + filesystem_object: String, + yanked: bool, +} + +pub async fn get_crate_versions( + conn: Arc>>, + crate_name: String, +) -> Vec { + use crate::schema::crates::dsl::*; + + tokio::task::spawn_blocking(move || { + let conn = conn.get().unwrap(); + + let selected_crate = crates + .filter(name.eq(crate_name)) + .first::(&conn) + .expect("no crate"); + let selected_crate_versions = CrateVersion::belonging_to(&selected_crate) + .load::(&conn) + .expect("no crate versions"); + + selected_crate_versions + }) + .await + .unwrap() +} + +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + assert_eq!(2 + 2, 4); + } +} diff --git a/chartered-db/src/schema.rs b/chartered-db/src/schema.rs new file mode 100644 index 0000000..31bea00 100644 --- /dev/null +++ a/chartered-db/src/schema.rs @@ -1,0 +1,23 @@ +table! { + crate_versions (id) { + id -> Integer, + crate_id -> Integer, + version -> Text, + filesystem_object -> Text, + yanked -> Bool, + } +} + +table! { + crates (id) { + id -> Integer, + name -> Text, + } +} + +joinable!(crate_versions -> crates (crate_id)); + +allow_tables_to_appear_in_same_query!( + crate_versions, + crates, +); diff --git a/chartered-web/src/main.rs b/chartered-web/src/main.rs index ad7525f..1765168 100644 --- a/chartered-web/src/main.rs +++ a/chartered-web/src/main.rs @@ -52,8 +52,12 @@ })) .into_inner(); + let pool = chartered_db::init(); + let app = Router::new() - .route("/", get(hello_world)) + .route("/", get(|| async move { + format!("{:#?}", chartered_db::get_crate_versions(pool, "cool-test-crate".to_string()).await) + })) .nest("/a/:key/api/v1", api_authenticated) .layer(middleware_stack); diff --git a/migrations/2021-08-31-214501_create_crates_table/down.sql b/migrations/2021-08-31-214501_create_crates_table/down.sql new file mode 100644 index 0000000..d012c2a 100644 --- /dev/null +++ a/migrations/2021-08-31-214501_create_crates_table/down.sql @@ -1,0 +1,2 @@ +DROP TABLE crates; +DROP TABLE crate_versions; diff --git a/migrations/2021-08-31-214501_create_crates_table/up.sql b/migrations/2021-08-31-214501_create_crates_table/up.sql new file mode 100644 index 0000000..3c766a0 100644 --- /dev/null +++ a/migrations/2021-08-31-214501_create_crates_table/up.sql @@ -1,0 +1,17 @@ +CREATE TABLE crates ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + name VARCHAR(255) NOT NULL UNIQUE +); + +CREATE TABLE crate_versions ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + crate_id INTEGER NOT NULL, + version VARCHAR(255) NOT NULL, + filesystem_object VARCHAR(255) NOT NULL, + yanked BOOLEAN NOT NULL DEFAULT FALSE, + UNIQUE (crate_id, version), + FOREIGN KEY (crate_id) REFERENCES crates (id) +); + +INSERT INTO crates VALUES (1, "cool-test-crate"); +INSERT INTO crate_versions VALUES (1, 1, "1.0.0", "cool-object", FALSE);-- rgit 0.1.3