diff options
| author | Ellie Huxtable <e@elm.sh> | 2021-04-20 17:07:11 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-04-20 16:07:11 +0000 |
| commit | 34888827f8a06de835cbe5833a06914f28cce514 (patch) | |
| tree | 8b56f20e50065cd2c222d5e8e067ec55cf1947a1 /src/server/handlers/history.rs | |
| parent | Optimise docker (#34) (diff) | |
| download | atuin-34888827f8a06de835cbe5833a06914f28cce514.zip | |
Switch to Warp + SQLx, use async, switch to Rust stable (#36)
* Switch to warp + sql, use async and stable rust
* Update CI to use stable
Diffstat (limited to 'src/server/handlers/history.rs')
| -rw-r--r-- | src/server/handlers/history.rs | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/server/handlers/history.rs b/src/server/handlers/history.rs new file mode 100644 index 00000000..4fd6f03f --- /dev/null +++ b/src/server/handlers/history.rs @@ -0,0 +1,89 @@ +use std::convert::Infallible; + +use warp::{http::StatusCode, reply::json}; + +use crate::api::{ + AddHistoryRequest, CountResponse, ErrorResponse, SyncHistoryRequest, SyncHistoryResponse, +}; +use crate::server::database::Database; +use crate::server::models::{NewHistory, User}; + +pub async fn count( + user: User, + db: impl Database + Clone + Send + Sync, +) -> Result<Box<dyn warp::Reply>, Infallible> { + db.count_history(&user).await.map_or( + Ok(Box::new(ErrorResponse::reply( + "failed to query history count", + StatusCode::INTERNAL_SERVER_ERROR, + ))), + |count| Ok(Box::new(json(&CountResponse { count }))), + ) +} + +pub async fn list( + req: SyncHistoryRequest, + user: User, + db: impl Database + Clone + Send + Sync, +) -> Result<Box<dyn warp::Reply>, Infallible> { + let history = db + .list_history( + &user, + req.sync_ts.naive_utc(), + req.history_ts.naive_utc(), + req.host, + ) + .await; + + if let Err(e) = history { + error!("failed to load history: {}", e); + let resp = + ErrorResponse::reply("failed to load history", StatusCode::INTERNAL_SERVER_ERROR); + let resp = Box::new(resp); + return Ok(resp); + } + + let history: Vec<String> = history + .unwrap() + .iter() + .map(|i| i.data.to_string()) + .collect(); + + debug!( + "loaded {} items of history for user {}", + history.len(), + user.id + ); + + Ok(Box::new(json(&SyncHistoryResponse { history }))) +} + +pub async fn add( + req: Vec<AddHistoryRequest>, + user: User, + db: impl Database + Clone + Send + Sync, +) -> Result<Box<dyn warp::Reply>, Infallible> { + debug!("request to add {} history items", req.len()); + + let history: Vec<NewHistory> = req + .iter() + .map(|h| NewHistory { + client_id: h.id.as_str(), + user_id: user.id, + hostname: h.hostname.as_str(), + timestamp: h.timestamp.naive_utc(), + data: h.data.as_str(), + }) + .collect(); + + if let Err(e) = db.add_history(&history).await { + error!("failed to add history: {}", e); + + return Ok(Box::new(ErrorResponse::reply( + "failed to add history", + StatusCode::INTERNAL_SERVER_ERROR, + ))); + }; + + Ok(Box::new(warp::reply())) +} |
