117 lines
3.0 KiB
Rust
117 lines
3.0 KiB
Rust
use crate::auth::Authenticated;
|
|
use crate::dtos::tracker::TrackerDTO;
|
|
use crate::models::AppState;
|
|
use crate::models::tracker::Tracker;
|
|
use crate::schema::hits::dsl as hits;
|
|
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>,
|
|
auth: Authenticated,
|
|
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,
|
|
auth: Authenticated,
|
|
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(auth: Authenticated, 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>?<delete_hits>")]
|
|
pub fn delete(
|
|
id: &str,
|
|
delete_hits: Option<bool>,
|
|
auth: Authenticated,
|
|
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 delete_hits = delete_hits.unwrap_or(false);
|
|
|
|
let count = diesel::delete(dsl::trackers.filter(dsl::id.eq(id)))
|
|
.execute(&mut *db)
|
|
.ok();
|
|
|
|
if delete_hits {
|
|
let hit_count =
|
|
diesel::delete(hits::hits.filter(hits::tracker_id.eq(id))).execute(&mut *db);
|
|
if let Err(err) = hit_count {
|
|
error!("Failed to delete associated hits: {}", err)
|
|
}
|
|
}
|
|
|
|
match count {
|
|
Some(count) if count > 0 => Ok(Status::Ok),
|
|
Some(_) => Ok(Status::NotFound),
|
|
None => Err(Status::InternalServerError),
|
|
}
|
|
}
|