about summary refs log tree commit diff stats
path: root/crates/rocie-server/src/storage/sql/insert
diff options
context:
space:
mode:
Diffstat (limited to 'crates/rocie-server/src/storage/sql/insert')
-rw-r--r--crates/rocie-server/src/storage/sql/insert/mod.rs1
-rw-r--r--crates/rocie-server/src/storage/sql/insert/product_parent/mod.rs4
-rw-r--r--crates/rocie-server/src/storage/sql/insert/recipe/mod.rs87
-rw-r--r--crates/rocie-server/src/storage/sql/insert/recipe_parent/mod.rs113
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,
+        }
+    }
+}