aboutsummaryrefslogtreecommitdiffstats
path: root/crates/rocie-server/src/storage/sql/insert
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-11-28 16:30:02 +0100
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-11-28 16:30:02 +0100
commita62ab5c6dacaddb67931d7ac160bc7faaa707737 (patch)
treea35fa3540fbb89f575ab1ea72f9b23ace399e01c /crates/rocie-server/src/storage/sql/insert
parentchore(crates/rocie-client): Re-generate (diff)
downloadserver-a62ab5c6dacaddb67931d7ac160bc7faaa707737.zip
feat(crates/rocie-server): Get closer to feature parity between rocie and grocy
Diffstat (limited to 'crates/rocie-server/src/storage/sql/insert')
-rw-r--r--crates/rocie-server/src/storage/sql/insert/mod.rs2
-rw-r--r--crates/rocie-server/src/storage/sql/insert/product/mod.rs6
-rw-r--r--crates/rocie-server/src/storage/sql/insert/product_parent/mod.rs113
-rw-r--r--crates/rocie-server/src/storage/sql/insert/recipe/mod.rs95
4 files changed, 214 insertions, 2 deletions
diff --git a/crates/rocie-server/src/storage/sql/insert/mod.rs b/crates/rocie-server/src/storage/sql/insert/mod.rs
index 3b2d702..8a15385 100644
--- a/crates/rocie-server/src/storage/sql/insert/mod.rs
+++ b/crates/rocie-server/src/storage/sql/insert/mod.rs
@@ -9,8 +9,10 @@ use sqlx::{SqliteConnection, query};
pub(crate) mod barcode;
pub(crate) mod product;
+pub(crate) mod product_parent;
pub(crate) mod unit;
pub(crate) mod unit_property;
+pub(crate) mod recipe;
pub(crate) trait Transactionable:
Sized + std::fmt::Debug + Serialize + DeserializeOwned
diff --git a/crates/rocie-server/src/storage/sql/insert/product/mod.rs b/crates/rocie-server/src/storage/sql/insert/product/mod.rs
index d762e9b..455eb4f 100644
--- a/crates/rocie-server/src/storage/sql/insert/product/mod.rs
+++ b/crates/rocie-server/src/storage/sql/insert/product/mod.rs
@@ -6,6 +6,7 @@ use crate::storage::sql::{
barcode::Barcode,
insert::{Operations, Transactionable},
product::{Product, ProductId},
+ product_parent::ProductParentId,
unit_property::UnitPropertyId,
};
@@ -15,7 +16,7 @@ pub(crate) enum Operation {
id: ProductId,
name: String,
description: Option<String>,
- parent: Option<ProductId>,
+ parent: Option<ProductParentId>,
unit_property: UnitPropertyId,
},
AssociateBarcode {
@@ -138,7 +139,7 @@ impl Product {
pub(crate) fn register(
name: String,
description: Option<String>,
- parent: Option<ProductId>,
+ parent: Option<ProductParentId>,
unit_property: UnitPropertyId,
ops: &mut Operations<Operation>,
) -> Self {
@@ -157,6 +158,7 @@ impl Product {
name,
description,
unit_property,
+ parent,
associated_bar_codes: vec![],
}
}
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
new file mode 100644
index 0000000..644778f
--- /dev/null
+++ b/crates/rocie-server/src/storage/sql/insert/product_parent/mod.rs
@@ -0,0 +1,113 @@
+use serde::{Deserialize, Serialize};
+use sqlx::query;
+use uuid::Uuid;
+
+use crate::storage::sql::{
+ insert::{Operations, Transactionable},
+ product_parent::{ProductParent, ProductParentId},
+};
+
+#[derive(Debug, Deserialize, Serialize)]
+pub(crate) enum Operation {
+ RegisterProductParent {
+ id: ProductParentId,
+ name: String,
+ description: Option<String>,
+ parent: Option<ProductParentId>,
+ },
+}
+
+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::RegisterProductParent {
+ id,
+ name,
+ description,
+ parent,
+ } => {
+ query!(
+ "
+ INSERT INTO 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::RegisterProductParent {
+ id,
+ name,
+ description,
+ parent,
+ } => {
+ query!(
+ "
+ DELETE FROM products
+ 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 ProductParent {
+ pub(crate) fn register(
+ name: String,
+ description: Option<String>,
+ parent: Option<ProductParentId>,
+ ops: &mut Operations<Operation>,
+ ) -> Self {
+ let id = ProductParentId::from(Uuid::new_v4());
+
+ ops.push(Operation::RegisterProductParent {
+ id,
+ name: name.clone(),
+ description: description.clone(),
+ parent,
+ });
+
+ Self {
+ id,
+ name,
+ description,
+ parent,
+ }
+ }
+}
diff --git a/crates/rocie-server/src/storage/sql/insert/recipe/mod.rs b/crates/rocie-server/src/storage/sql/insert/recipe/mod.rs
new file mode 100644
index 0000000..b223bfe
--- /dev/null
+++ b/crates/rocie-server/src/storage/sql/insert/recipe/mod.rs
@@ -0,0 +1,95 @@
+use std::path::PathBuf;
+
+use serde::{Deserialize, Serialize};
+use sqlx::query;
+use uuid::Uuid;
+
+use crate::storage::sql::{
+ insert::{Operations, Transactionable},
+ recipe::{Recipe, RecipeId},
+};
+
+#[derive(Debug, Deserialize, Serialize)]
+pub(crate) enum Operation {
+ New {
+ id: RecipeId,
+ path: PathBuf,
+ content: String,
+ },
+}
+
+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::New { id, path, content } => {
+ let path = path.display().to_string();
+
+ query!(
+ "
+ INSERT INTO recipies (id, path, content)
+ VALUES (?, ?, ?)
+",
+ id,
+ path,
+ content,
+ )
+ .execute(txn)
+ .await?;
+ }
+ }
+ Ok(())
+ }
+
+ async fn undo(self, txn: &mut sqlx::SqliteConnection) -> Result<(), undo::Error> {
+ match self {
+ Operation::New { id, path, content } => {
+ let path = path.display().to_string();
+
+ query!(
+ "
+ DELETE FROM recipies
+ WHERE id = ? AND path = ? AND content = ?
+",
+ id,
+ path,
+ content
+ )
+ .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 Recipe {
+ pub(crate) fn new(path: PathBuf, content: String, ops: &mut Operations<Operation>) -> Self {
+ let id = RecipeId::from(Uuid::new_v4());
+
+ ops.push(Operation::New {
+ id,
+ path: path.clone(),
+ content: content.clone(),
+ });
+
+ Self { id, path, content }
+ }
+}