From f45900d69db00b17d3f552f1f0291bc9307aea21 Mon Sep 17 00:00:00 2001 From: Daniel Svitan Date: Sun, 5 Oct 2025 20:35:23 +0200 Subject: [PATCH] :sparkles: Adds hit route --- src/api/hit.rs | 75 +++++++++++++++++++++++++++++++++++++++++++++ src/api/mod.rs | 1 + src/api/tracker.rs | 2 ++ src/main.rs | 2 ++ static/image.png | Bin 0 -> 68 bytes 5 files changed, 80 insertions(+) create mode 100644 src/api/hit.rs create mode 100644 static/image.png diff --git a/src/api/hit.rs b/src/api/hit.rs new file mode 100644 index 0000000..cc2c2e3 --- /dev/null +++ b/src/api/hit.rs @@ -0,0 +1,75 @@ +use crate::dtos::hit::HitDTO; +use crate::models::AppState; +use crate::models::hit::Hit; +use crate::schema::hits; +use crate::schema::hits::dsl; +use diesel::ExpressionMethods; +use diesel::{QueryDsl, RunQueryDsl, SelectableHelper}; +use rocket::State; +use rocket::http::Status; +use rocket::serde::json::Json; +use uuid::Uuid; + +#[get("/?&")] +pub fn index( + offset: Option, + limit: Option, + state: &State, +) -> Result>, Status> { + let mut db = state.db.lock().unwrap(); + + let offset = offset.unwrap_or(0); + let limit = limit.unwrap_or(10); + + let results = dsl::hits + .offset(offset) + .limit(limit) + .select(Hit::as_select()) + .load(&mut *db) + .ok(); + + match results { + Some(results) => Ok(Json(results.iter().map(HitDTO::from).collect())), + None => Err(Status::InternalServerError), + } +} + +#[get("/")] +pub fn get(id: String, state: &State) -> Result, Status> { + let mut db = state.db.lock().unwrap(); + + let id = match Uuid::parse_str(id.as_str()).ok() { + Some(id) => id, + None => return Err(Status::BadRequest), + }; + + let result = dsl::hits + .filter(hits::id.eq(id)) + .first::(&mut *db) + .ok(); + + match result { + Some(tracker) => Ok(Json(HitDTO::from(&tracker))), + None => Err(Status::NotFound), + } +} + +#[delete("/")] +pub fn delete(id: String, state: &State) -> Result { + let mut db = state.db.lock().unwrap(); + + let id = match Uuid::parse_str(id.as_str()).ok() { + Some(id) => id, + None => return Err(Status::BadRequest), + }; + + let count = diesel::delete(dsl::hits.filter(dsl::id.eq(id))) + .execute(&mut *db) + .ok(); + + match count { + Some(count) if count > 0 => Ok(Status::Ok), + Some(_) => Ok(Status::NotFound), + None => Err(Status::InternalServerError), + } +} diff --git a/src/api/mod.rs b/src/api/mod.rs index e660e7e..ef0b7fa 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -1 +1,2 @@ pub mod tracker; +pub mod hit; diff --git a/src/api/tracker.rs b/src/api/tracker.rs index 43c6019..d662cd4 100644 --- a/src/api/tracker.rs +++ b/src/api/tracker.rs @@ -87,6 +87,8 @@ pub fn delete(id: String, state: &State) -> Result { .execute(&mut *db) .ok(); + // TODO: maybe delete all associated hits? + match count { Some(count) if count > 0 => Ok(Status::Ok), Some(_) => Ok(Status::NotFound), diff --git a/src/main.rs b/src/main.rs index b1ab378..211b25d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ mod dtos; mod models; mod schema; +use crate::api::hit; use crate::api::tracker; use diesel::{Connection, PgConnection}; use std::env; @@ -36,4 +37,5 @@ fn rocket() -> _ { tracker::delete ], ) + .mount("/hit", routes![hit::index, hit::get, hit::delete]) } diff --git a/static/image.png b/static/image.png new file mode 100644 index 0000000000000000000000000000000000000000..3c86ed194c66bb0d6e27a6b1804b826ae8081782 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx1|;Q0k8}blZci7-5RT~N1O_Gs237_}Ir%pt PKw$