introduce diesel for state management
Diff
.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(-)
@@ -1,0 +1,1 @@
DATABASE_URL=chartered.db
@@ -1,2 +1,3 @@
/target
.idea/
/chartered.db
@@ -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"
@@ -1,6 +1,7 @@
[workspace]
members = [
"chartered-git",
"chartered-web",
"chartered-fs",
"chartered-db",
]
@@ -1,0 +1,5 @@
[print_schema]
file = "chartered-db/src/schema.rs"
@@ -1,0 +1,11 @@
[package]
name = "chartered-db"
version = "0.1.0"
edition = "2018"
[dependencies]
diesel = { version = "1", features = ["sqlite", "r2d2"] }
tokio = { version = "1" }
dotenv = "0.15"
@@ -1,0 +1,3 @@
# chartered-db (library)
Defines the database schema and corresponding queries for chartered.
@@ -6,6 +6,8 @@
[dependencies]
chartered-db = { path = "../chartered-db" }
axum = "0.2"
futures = "0.3"
tokio = { version = "1", features = ["full"] }
@@ -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<Pool<ConnectionManager<diesel::SqliteConnection>>> {
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<Pool<ConnectionManager<diesel::SqliteConnection>>>,
crate_name: String,
) -> Vec<CrateVersion> {
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::<Crate>(&conn)
.expect("no crate");
let selected_crate_versions = CrateVersion::belonging_to(&selected_crate)
.load::<CrateVersion>(&conn)
.expect("no crate versions");
selected_crate_versions
})
.await
.unwrap()
}
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}
@@ -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,
);
@@ -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);
@@ -1,0 +1,2 @@
DROP TABLE crates;
DROP TABLE crate_versions;
@@ -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);