use crate::dtos::tracker::TrackerDTO; use crate::models::AppState; use crate::models::tracker::Tracker; use crate::schema::trackers; use crate::schema::trackers::dsl; use chrono::Utc; use diesel::{ExpressionMethods, 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::trackers .offset(offset) .limit(limit) .select(Tracker::as_select()) .load(&mut *db) .ok(); match results { Some(results) => Ok(Json(results.iter().map(TrackerDTO::from).collect())), None => Err(Status::InternalServerError), } } #[get("/")] pub fn get(id: &str, state: &State) -> Result, Status> { let mut db = state.db.lock().unwrap(); let id = match Uuid::parse_str(id).ok() { Some(id) => id, None => return Err(Status::BadRequest), }; let result = dsl::trackers .filter(trackers::id.eq(id)) .first::(&mut *db) .ok(); match result { Some(tracker) => Ok(Json(TrackerDTO::from(&tracker))), None => Err(Status::NotFound), } } #[post("/")] pub fn create(state: &State) -> Result, Status> { let mut db = state.db.lock().unwrap(); let new = Tracker { id: Uuid::new_v4(), created_at: Utc::now().naive_utc(), }; let result = diesel::insert_into(trackers::table) .values(&new) .returning(Tracker::as_returning()) .get_result(&mut *db) .ok(); match result { Some(tracker) => Ok(Json(TrackerDTO::from(&tracker))), None => Err(Status::InternalServerError), } } #[delete("/")] pub fn delete(id: &str, state: &State) -> Result { let mut db = state.db.lock().unwrap(); let id = match Uuid::parse_str(id).ok() { Some(id) => id, None => return Err(Status::BadRequest), }; let count = diesel::delete(dsl::trackers.filter(dsl::id.eq(id))) .execute(&mut *db) .ok(); // TODO: maybe delete all associated hits? match count { Some(count) if count > 0 => Ok(Status::Ok), Some(_) => Ok(Status::NotFound), None => Err(Status::InternalServerError), } }