diff --git a/kitchen/sqlx-data.json b/kitchen/sqlx-data.json index f0e9513..443fa09 100644 --- a/kitchen/sqlx-data.json +++ b/kitchen/sqlx-data.json @@ -240,6 +240,16 @@ }, "query": "select content from staples where user_id = ?" }, + "6c43908d90f229b32ed8b1b076be9b452a995e1b42ba2554e947c515b031831a": { + "describe": { + "columns": [], + "nullable": [], + "parameters": { + "Right": 2 + } + }, + "query": "delete from recipes where user_id = ? and recipe_id = ?" + }, "6e28698330e42fd6c87ba1e6f1deb664c0d3995caa2b937ceac8c908e98aded6": { "describe": { "columns": [], diff --git a/kitchen/src/web/mod.rs b/kitchen/src/web/mod.rs index 60df730..f40701b 100644 --- a/kitchen/src/web/mod.rs +++ b/kitchen/src/web/mod.rs @@ -99,6 +99,29 @@ async fn api_recipe_entry( result.into() } +async fn api_recipe_delete( + Extension(app_store): Extension>, + session: storage::UserIdFromSession, + Path(recipe_id): Path, +) -> api::EmptyResponse { + use storage::{UserId, UserIdFromSession::*}; + let result = match session { + NoUserId => api::EmptyResponse::Unauthorized, + FoundUserId(UserId(id)) => { + if let Err(e) = app_store + .delete_recipes_for_user(&id, &vec![recipe_id]) + .await + .map_err(|e| format!("Error: {:?}", e)) + { + api::EmptyResponse::error(StatusCode::INTERNAL_SERVER_ERROR.as_u16(), e) + } else { + api::EmptyResponse::success(()) + } + } + }; + result.into() +} + #[instrument] async fn api_recipes( Extension(store): Extension>, @@ -445,7 +468,10 @@ fn mk_v2_routes() -> Router { Router::new() .route("/recipes", get(api_recipes).post(api_save_recipes)) // recipe entry api path route - .route("/recipe/:recipe_id", get(api_recipe_entry)) + .route( + "/recipe/:recipe_id", + get(api_recipe_entry).delete(api_recipe_delete), + ) // mealplan api path routes .route("/plan", get(api_plan).post(api_save_plan)) .route("/plan/:date", get(api_plan_since)) diff --git a/kitchen/src/web/storage/mod.rs b/kitchen/src/web/storage/mod.rs index 331dc14..13545ef 100644 --- a/kitchen/src/web/storage/mod.rs +++ b/kitchen/src/web/storage/mod.rs @@ -103,6 +103,8 @@ pub trait APIStore { async fn get_recipes_for_user(&self, user_id: &str) -> Result>>; + async fn delete_recipes_for_user(&self, user_id: &str, recipes: &Vec) -> Result<()>; + async fn store_recipes_for_user(&self, user_id: &str, recipes: &Vec) -> Result<()>; @@ -467,6 +469,21 @@ impl APIStore for SqliteStore { Ok(()) } + async fn delete_recipes_for_user(&self, user_id: &str, recipes: &Vec) -> Result<()> { + let mut transaction = self.pool.as_ref().begin().await?; + for recipe_id in recipes { + sqlx::query!( + "delete from recipes where user_id = ? and recipe_id = ?", + user_id, + recipe_id, + ) + .execute(&mut transaction) + .await?; + } + transaction.commit().await?; + Ok(()) + } + async fn store_categories_for_user(&self, user_id: &str, categories: &str) -> Result<()> { sqlx::query!( "insert into categories (user_id, category_text) values (?, ?)