Files
setra/src/api/tracker.rs
2025-10-06 16:38:44 +02:00

98 lines
2.6 KiB
Rust

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("/?<offset>&<limit>")]
pub fn index(
offset: Option<i64>,
limit: Option<i64>,
state: &State<AppState>,
) -> Result<Json<Vec<TrackerDTO>>, 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("/<id>")]
pub fn get(id: &str, state: &State<AppState>) -> Result<Json<TrackerDTO>, 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::<Tracker>(&mut *db)
.ok();
match result {
Some(tracker) => Ok(Json(TrackerDTO::from(&tracker))),
None => Err(Status::NotFound),
}
}
#[post("/")]
pub fn create(state: &State<AppState>) -> Result<Json<TrackerDTO>, 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("/<id>")]
pub fn delete(id: &str, state: &State<AppState>) -> Result<Status, 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 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),
}
}