summaryrefslogtreecommitdiff
path: root/schist_backend
diff options
context:
space:
mode:
authorJoe Carstairs <me@joeac.net>2024-12-12 08:28:04 +0000
committerJoe Carstairs <me@joeac.net>2024-12-12 08:28:04 +0000
commit54894f9de9bad4fecb2a116d59a03cdd003f84c0 (patch)
tree6ce5517cecf23d4e93d7a381a374e1fa6c810cee /schist_backend
parent8a30bcbdf9264d235bf93da3df8e170cfde53d02 (diff)
Moves rust workspace to root
Diffstat (limited to 'schist_backend')
-rw-r--r--schist_backend/Cargo.toml16
-rw-r--r--schist_backend/Rocket.toml2
-rw-r--r--schist_backend/diesel.toml9
-rw-r--r--schist_backend/src/databases.rs11
-rw-r--r--schist_backend/src/main.rs48
-rw-r--r--schist_backend/src/routes/account.rs48
-rw-r--r--schist_backend/src/routes/category.rs16
-rw-r--r--schist_backend/src/routes/mod.rs2
8 files changed, 152 insertions, 0 deletions
diff --git a/schist_backend/Cargo.toml b/schist_backend/Cargo.toml
new file mode 100644
index 0000000..1faa9d8
--- /dev/null
+++ b/schist_backend/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "schist_backend"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+chrono = { workspace = true, features = ["serde"] }
+cfg-if = { workspace = true }
+diesel = { workspace = true, features = ["sqlite"] }
+diesel_migrations = { workspace = true }
+libsqlite3-sys = { workspace = true, features = ["bundled"] }
+rocket = { workspace = true, features = ["json"] }
+rocket_sync_db_pools = { workspace = true, features = ["diesel_sqlite_pool"] }
+schist_models = { path = "../schist_models" }
+schist_queries = { path = "../schist_queries" }
+schist_schema = { path = "../schist_schema" }
diff --git a/schist_backend/Rocket.toml b/schist_backend/Rocket.toml
new file mode 100644
index 0000000..088d632
--- /dev/null
+++ b/schist_backend/Rocket.toml
@@ -0,0 +1,2 @@
+[global.databases]
+user_data = { url = "/home/joeac/src/budgeting-app/backend/core/user_data.sqlite" }
diff --git a/schist_backend/diesel.toml b/schist_backend/diesel.toml
new file mode 100644
index 0000000..a0d61bf
--- /dev/null
+++ b/schist_backend/diesel.toml
@@ -0,0 +1,9 @@
+# For documentation on how to configure this file,
+# see https://diesel.rs/guides/configuring-diesel-cli
+
+[print_schema]
+file = "src/schema.rs"
+custom_type_derives = ["diesel::query_builder::QueryId", "Clone"]
+
+[migrations_directory]
+dir = "migrations"
diff --git a/schist_backend/src/databases.rs b/schist_backend/src/databases.rs
new file mode 100644
index 0000000..7202e78
--- /dev/null
+++ b/schist_backend/src/databases.rs
@@ -0,0 +1,11 @@
+use rocket_sync_db_pools::{database, diesel};
+
+cfg_if::cfg_if! {
+ if #[cfg(test)] {
+ #[database("user_data.test")]
+ pub struct UserDataDb(diesel::SqliteConnection);
+ } else {
+ #[database("user_data")]
+ pub struct UserDataDb(diesel::SqliteConnection);
+ }
+}
diff --git a/schist_backend/src/main.rs b/schist_backend/src/main.rs
new file mode 100644
index 0000000..8395681
--- /dev/null
+++ b/schist_backend/src/main.rs
@@ -0,0 +1,48 @@
+use schist_schema::migrations::MIGRATIONS;
+use diesel::SqliteConnection;
+use diesel_migrations::MigrationHarness;
+use rocket::fairing::AdHoc;
+use rocket::http::ContentType;
+use rocket::{launch, routes, Build, Rocket};
+
+use crate::databases::UserDataDb;
+
+pub mod databases;
+pub mod routes;
+
+fn run_database_migrations(connection: &mut SqliteConnection) {
+ connection
+ .run_pending_migrations(MIGRATIONS)
+ .expect("Error running database migrations");
+}
+
+#[launch]
+async fn rocket() -> Rocket<Build> {
+ rocket::build()
+ .attach(UserDataDb::fairing())
+ .attach(AdHoc::on_liftoff("Database Migration", |rocket| {
+ Box::pin(async move {
+ let user_data_db = UserDataDb::get_one(rocket).await.expect(
+ "Failed to get connection to user data database in order to run migrations",
+ );
+ user_data_db.run(run_database_migrations).await;
+ })
+ }))
+ .attach(AdHoc::on_response("Add CORS headers", |_req, res| {
+ Box::pin(async move {
+ res.set_header(ContentType::JSON);
+ res.set_header(rocket::http::Header::new(
+ "Access-Control-Allow-Origin",
+ "http://localhost:5173",
+ ));
+ })
+ }))
+ .mount(
+ "/",
+ routes![
+ routes::account::get_all_accounts,
+ routes::account::create_account,
+ routes::category::get_all_categories,
+ ],
+ )
+}
diff --git a/schist_backend/src/routes/account.rs b/schist_backend/src/routes/account.rs
new file mode 100644
index 0000000..83d4d1b
--- /dev/null
+++ b/schist_backend/src/routes/account.rs
@@ -0,0 +1,48 @@
+use schist_models::account::Account;
+use schist_queries::accounts::{get_all_accounts as get_all_accounts_query, insert_accounts};
+use rocket::http::Status;
+use rocket::serde::json::Json;
+use rocket::{get, post, Responder};
+
+use crate::databases::UserDataDb;
+
+#[get("/account")]
+pub async fn get_all_accounts(user_data_db: UserDataDb) -> Result<Json<Vec<Account>>, (Status, String)> {
+ user_data_db
+ .run(get_all_accounts_query)
+ .await
+ .map(Json)
+ .map_err(|err| (Status::InternalServerError, err.to_string()))
+}
+
+#[derive(Responder)]
+pub enum CreateAccountResponder {
+ #[response(status = 500, content_type = "text")]
+ InternalServerError(String),
+
+ #[response(status = 202, content_type = "json")]
+ Created(Json<Account>),
+
+ #[response(status = 400, content_type = "text")]
+ BadRequest(String),
+}
+
+#[post("/account", data = "<account>", format = "json")]
+pub async fn create_account(
+ account: Json<Account>,
+ user_data_db: UserDataDb,
+) -> CreateAccountResponder {
+ let account = account.into_inner();
+ let accounts_vec = vec![account.clone()];
+
+ let num_rows_inserted = user_data_db
+ .run(move |connection| insert_accounts(&accounts_vec, connection))
+ .await;
+
+ match num_rows_inserted {
+ Ok(_) => CreateAccountResponder::Created(Json(account)),
+ Err(err) => CreateAccountResponder::InternalServerError(format!(
+ "Error creating account: {err}"
+ )),
+ }
+}
diff --git a/schist_backend/src/routes/category.rs b/schist_backend/src/routes/category.rs
new file mode 100644
index 0000000..b2412ac
--- /dev/null
+++ b/schist_backend/src/routes/category.rs
@@ -0,0 +1,16 @@
+use rocket::get;
+use rocket::http::Status;
+use rocket::serde::json::Json;
+use schist_models::category::Category;
+use schist_queries::categories::get_all_categories as get_all_categories_query;
+
+use crate::databases::UserDataDb;
+
+#[get("/category")]
+pub async fn get_all_categories(user_data_db: UserDataDb) -> Result<Json<Vec<Category>>, Status> {
+ user_data_db
+ .run(get_all_categories_query)
+ .await
+ .map(Json)
+ .map_err(|_| Status { code: 500 })
+}
diff --git a/schist_backend/src/routes/mod.rs b/schist_backend/src/routes/mod.rs
new file mode 100644
index 0000000..e22565c
--- /dev/null
+++ b/schist_backend/src/routes/mod.rs
@@ -0,0 +1,2 @@
+pub mod account;
+pub mod category;