diff options
| author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-02-15 22:24:32 +0100 |
|---|---|---|
| committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-02-15 22:25:06 +0100 |
| commit | e5f90f4474cb96a78080395980283e4b2ce40214 (patch) | |
| tree | caac3300795eae8e4cb1ee3c1c4bf85cd5950402 /crates/rocie-server/src/storage/sql/insert | |
| parent | chore(treewide): Update (diff) | |
| download | server-e5f90f4474cb96a78080395980283e4b2ce40214.zip | |
feat(treewide): Add recipes and user handling
Diffstat (limited to 'crates/rocie-server/src/storage/sql/insert')
4 files changed, 182 insertions, 23 deletions
diff --git a/crates/rocie-server/src/storage/sql/insert/mod.rs b/crates/rocie-server/src/storage/sql/insert/mod.rs index 673cbdd..b92a88c 100644 --- a/crates/rocie-server/src/storage/sql/insert/mod.rs +++ b/crates/rocie-server/src/storage/sql/insert/mod.rs @@ -11,6 +11,7 @@ pub(crate) mod barcode; pub(crate) mod product; pub(crate) mod product_parent; pub(crate) mod recipe; +pub(crate) mod recipe_parent; pub(crate) mod unit; pub(crate) mod unit_property; pub(crate) mod user; diff --git a/crates/rocie-server/src/storage/sql/insert/product_parent/mod.rs b/crates/rocie-server/src/storage/sql/insert/product_parent/mod.rs index 644778f..72fb564 100644 --- a/crates/rocie-server/src/storage/sql/insert/product_parent/mod.rs +++ b/crates/rocie-server/src/storage/sql/insert/product_parent/mod.rs @@ -31,7 +31,7 @@ impl Transactionable for Operation { } => { query!( " - INSERT INTO parents (id, name, description, parent) + INSERT INTO product_parents (id, name, description, parent) VALUES (?,?,?,?) ", id, @@ -56,7 +56,7 @@ impl Transactionable for Operation { } => { query!( " - DELETE FROM products + DELETE FROM product_parents WHERE id = ? AND name = ? AND description = ? AND parent = ?; ", id, diff --git a/crates/rocie-server/src/storage/sql/insert/recipe/mod.rs b/crates/rocie-server/src/storage/sql/insert/recipe/mod.rs index b223bfe..b60874f 100644 --- a/crates/rocie-server/src/storage/sql/insert/recipe/mod.rs +++ b/crates/rocie-server/src/storage/sql/insert/recipe/mod.rs @@ -1,19 +1,23 @@ -use std::path::PathBuf; - +use cooklang::{Converter, CooklangParser, Extensions}; use serde::{Deserialize, Serialize}; use sqlx::query; use uuid::Uuid; -use crate::storage::sql::{ - insert::{Operations, Transactionable}, - recipe::{Recipe, RecipeId}, +use crate::{ + app::App, + storage::sql::{ + insert::{Operations, Transactionable}, + recipe::{CooklangRecipe, Recipe, RecipeId}, + recipe_parent::RecipeParentId, + }, }; #[derive(Debug, Deserialize, Serialize)] pub(crate) enum Operation { New { id: RecipeId, - path: PathBuf, + name: String, + parent: Option<RecipeParentId>, content: String, }, } @@ -24,16 +28,20 @@ impl Transactionable for Operation { async fn apply(self, txn: &mut sqlx::SqliteConnection) -> Result<(), apply::Error> { match self { - Operation::New { id, path, content } => { - let path = path.display().to_string(); - + Operation::New { + id, + name, + parent, + content, + } => { query!( " - INSERT INTO recipies (id, path, content) - VALUES (?, ?, ?) + INSERT INTO recipies (id, name, parent, content) + VALUES (?, ?, ?, ?) ", id, - path, + name, + parent, content, ) .execute(txn) @@ -45,16 +53,20 @@ impl Transactionable for Operation { async fn undo(self, txn: &mut sqlx::SqliteConnection) -> Result<(), undo::Error> { match self { - Operation::New { id, path, content } => { - let path = path.display().to_string(); - + Operation::New { + id, + name, + parent, + content, + } => { query!( " DELETE FROM recipies - WHERE id = ? AND path = ? AND content = ? + WHERE id = ? AND name = ? AND parent = ? AND content = ? ", id, - path, + name, + parent, content ) .execute(txn) @@ -79,17 +91,50 @@ pub(crate) mod apply { SqlError(#[from] sqlx::Error), } } +pub(crate) mod new { + use actix_web::ResponseError; + + use crate::storage::sql::recipe::conversion; + + #[derive(thiserror::Error, Debug)] + pub(crate) enum Error { + #[error("Failed to parse the recipe contents as cooklang: `{0}`")] + RecipeParse(#[from] cooklang::error::SourceReport), + + #[error("Failed to convert the cooklang recipe to our struct: `{0}`")] + RecipeConvert(#[from] conversion::Error), + } + + impl ResponseError for Error {} +} impl Recipe { - pub(crate) fn new(path: PathBuf, content: String, ops: &mut Operations<Operation>) -> Self { + pub(crate) async fn new( + app: &App, + name: String, + parent: Option<RecipeParentId>, + content: String, + ops: &mut Operations<Operation>, + ) -> Result<Self, new::Error> { let id = RecipeId::from(Uuid::new_v4()); + let parser = CooklangParser::new(Extensions::empty(), Converter::bundled()); + + // TODO: Somehow return the warnings <2026-01-31> + let (recipe, _warnings) = parser.parse(&content).into_result()?; + ops.push(Operation::New { id, - path: path.clone(), - content: content.clone(), + content, + name: name.clone(), + parent, }); - Self { id, path, content } + Ok(Self { + id, + name, + parent, + content: CooklangRecipe::from(app, recipe).await?, + }) } } diff --git a/crates/rocie-server/src/storage/sql/insert/recipe_parent/mod.rs b/crates/rocie-server/src/storage/sql/insert/recipe_parent/mod.rs new file mode 100644 index 0000000..95bc6f1 --- /dev/null +++ b/crates/rocie-server/src/storage/sql/insert/recipe_parent/mod.rs @@ -0,0 +1,113 @@ +use serde::{Deserialize, Serialize}; +use sqlx::query; +use uuid::Uuid; + +use crate::storage::sql::{ + insert::{Operations, Transactionable}, + recipe_parent::{RecipeParent, RecipeParentId}, +}; + +#[derive(Debug, Deserialize, Serialize)] +pub(crate) enum Operation { + RegisterRecipeParent { + id: RecipeParentId, + name: String, + description: Option<String>, + parent: Option<RecipeParentId>, + }, +} + +impl Transactionable for Operation { + type ApplyError = apply::Error; + type UndoError = undo::Error; + + async fn apply(self, txn: &mut sqlx::SqliteConnection) -> Result<(), apply::Error> { + match self { + Operation::RegisterRecipeParent { + id, + name, + description, + parent, + } => { + query!( + " + INSERT INTO recipe_parents (id, name, description, parent) + VALUES (?,?,?,?) +", + id, + name, + description, + parent + ) + .execute(txn) + .await?; + } + } + Ok(()) + } + + async fn undo(self, txn: &mut sqlx::SqliteConnection) -> Result<(), undo::Error> { + match self { + Operation::RegisterRecipeParent { + id, + name, + description, + parent, + } => { + query!( + " + DELETE FROM recipe_parents + WHERE id = ? AND name = ? AND description = ? AND parent = ?; +", + id, + name, + description, + parent, + ) + .execute(txn) + .await?; + } + } + Ok(()) + } +} + +pub(crate) mod undo { + #[derive(thiserror::Error, Debug)] + pub(crate) enum Error { + #[error("Failed to execute undo sql statments: {0}")] + SqlError(#[from] sqlx::Error), + } +} +pub(crate) mod apply { + #[derive(thiserror::Error, Debug)] + pub(crate) enum Error { + #[error("Failed to execute apply sql statments: {0}")] + SqlError(#[from] sqlx::Error), + } +} + +impl RecipeParent { + pub(crate) fn register( + name: String, + description: Option<String>, + parent: Option<RecipeParentId>, + ops: &mut Operations<Operation>, + ) -> Self { + let id = RecipeParentId::from(Uuid::new_v4()); + + ops.push(Operation::RegisterRecipeParent { + id, + name: name.clone(), + description: description.clone(), + parent, + }); + + Self { + id, + name, + description, + parent, + } + } +} |
