From 7a1dee61c966ba030edc4f08c137538f86d8dd60 Mon Sep 17 00:00:00 2001 From: "D. Scott Boggs" Date: Sun, 25 Jun 2023 14:32:02 -0400 Subject: [PATCH] Add updates for track changes --- server/src/api/import.rs | 16 ++++------------ server/src/api/tracks.rs | 40 ++++++++++++++++++++++++---------------- server/src/api/update.rs | 33 ++++++++++++++++++++++++++++++++- 3 files changed, 60 insertions(+), 29 deletions(-) diff --git a/server/src/api/import.rs b/server/src/api/import.rs index 956de57..462930b 100644 --- a/server/src/api/import.rs +++ b/server/src/api/import.rs @@ -8,10 +8,7 @@ use crate::error::Error; use super::error::ApiResult; #[post("/dump", data = "")] -pub(crate) async fn sql_dump( - db: &State, - sql_dump: &str, -) -> ApiResult { +pub(crate) async fn sql_dump(db: &State, sql_dump: &str) -> ApiResult { for line in sql_dump.lines() { let line = line.to_ascii_lowercase(); if line.starts_with("insert into") @@ -25,11 +22,8 @@ pub(crate) async fn sql_dump( Ok(Status::Ok) } -#[post("/", data="")] -pub(crate) async fn db_file( - db: &State, - sqlite_db: &[u8], -) -> ApiResult { +#[post("/", data = "")] +pub(crate) async fn db_file(db: &State, sqlite_db: &[u8]) -> ApiResult { use std::{ io::Write, process::{Command, Stdio}, @@ -51,8 +45,6 @@ pub(crate) async fn db_file( if result.status.success() { sql_dump(db, &String::from_utf8(result.stdout).map_err(Error::from)?).await } else { - Err(Error::SqliteCommandError(String::from_utf8_lossy( - &result.stderr, - ).to_string()).into()) + Err(Error::SqliteCommandError(String::from_utf8_lossy(&result.stderr).to_string()).into()) } } diff --git a/server/src/api/tracks.rs b/server/src/api/tracks.rs index a292ea7..c14789b 100644 --- a/server/src/api/tracks.rs +++ b/server/src/api/tracks.rs @@ -5,7 +5,6 @@ use either::Either::{self, Left, Right}; use rocket::http::Status; use rocket::{serde::json::Json, State}; use sea_orm::{prelude::*, DatabaseConnection}; -use std::default::default; use tokio::sync::broadcast::Sender; use super::update::Update; @@ -54,37 +53,46 @@ pub(super) async fn ticks_for_track( #[post("/", format = "application/json", data = "")] pub(super) async fn insert_track( db: &State, + tx: &State>, track: Json, ) -> ApiResult> { let track = track.0; let db = db as &DatabaseConnection; - let mut model: tracks::ActiveModel = default(); - model.set_from_json(track).map_err(Error::from)?; - Ok(Json(model.insert(db).await.map_err(Error::from)?)) + let model = tracks::ActiveModel::from_json(track).map_err(Error::from)?; + let track = model.insert(db).await.map_err(Error::from)?; + tx.send(Update::track_added(track.clone())) + .map_err(Error::from)?; + Ok(Json(track)) } #[put("/", format = "application/json", data = "")] pub(super) async fn update_track( db: &State, + tx: &State>, track: Json, ) -> ApiResult> { let db = db as &DatabaseConnection; - Ok(Json( - tracks::ActiveModel::from_json(track.0) - .map_err(Error::from)? - .update(db) - .await - .map_err(Error::from)?, - )) + let track = tracks::ActiveModel::from_json(track.0) + .map_err(Error::from)? + .update(db) + .await + .map_err(Error::from)?; + tx.send(Update::track_changed(track.clone())) + .map_err(Error::from)?; + Ok(Json(track)) } #[delete("/")] -pub(super) async fn delete_track(db: &State, id: i32) -> ApiResult { +pub(super) async fn delete_track( + db: &State, + tx: &State>, + id: i32, +) -> ApiResult { let db = db as &DatabaseConnection; - Tracks::delete_by_id(id) - .exec(db) - .await - .map_err(Error::from)?; + let Some(track) = Tracks::find_by_id(id).one(db).await.map_err(Error::from)? else { + return Ok(Status::NotFound); + }; + tx.send(Update::track_removed(track)).map_err(Error::from)?; Ok(Status::Ok) } diff --git a/server/src/api/update.rs b/server/src/api/update.rs index 0b6adba..1135c18 100644 --- a/server/src/api/update.rs +++ b/server/src/api/update.rs @@ -4,7 +4,10 @@ use serde::{Deserialize, Serialize}; use serde_json::json; use tokio::sync::broadcast::Sender; -use crate::{entities::ticks, error::Result}; +use crate::{ + entities::{ticks, tracks}, + error::Result, +}; #[derive(Debug, Clone, Serialize, Deserialize)] pub enum Update { @@ -16,6 +19,10 @@ pub enum Update { kind: UpdateType, count: u64, }, + TrackChanged { + kind: UpdateType, + track: tracks::Model, + }, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -23,6 +30,9 @@ pub enum Update { pub enum UpdateType { TickAdded, TickDropped, + TrackAdded, + TrackChanged, + TrackDropped, Error, } @@ -48,6 +58,26 @@ impl Update { } } + pub fn track_added(track: tracks::Model) -> Self { + Self::TrackChanged { + kind: UpdateType::TrackAdded, + track, + } + } + + pub fn track_removed(track: tracks::Model) -> Self { + Self::TrackChanged { + kind: UpdateType::TrackDropped, + track, + } + } + + pub fn track_changed(track: tracks::Model) -> Self { + Self::TrackChanged { + kind: UpdateType::TrackChanged, + track, + } + } pub fn to_event(&self) -> Event { use Update::*; match self { @@ -56,6 +86,7 @@ impl Update { Event::json(&json! {{"message": "error: lagged", "count": count}}) .event(format!("{kind:?}")) } + TrackChanged { kind, track } => Event::json(track).event(format!("{kind:?}")), } }