// rocie - An enterprise grocery management system // // Copyright (C) 2026 Benedikt Peetz // SPDX-License-Identifier: GPL-3.0-or-later // // This file is part of Rocie. // // You should have received a copy of the License along with this program. // If not, see . use serde::{Deserialize, Serialize}; use sqlx::query; use uuid::Uuid; use crate::storage::sql::{ insert::{Operations, Transactionable}, unit::{Unit, UnitId}, unit_property::UnitPropertyId, }; #[derive(Debug, Deserialize, Serialize)] pub(crate) enum Operation { RegisterUnit { id: UnitId, full_name_singular: String, full_name_plural: String, short_name: String, unit_property: UnitPropertyId, description: Option, }, } 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::RegisterUnit { id, full_name_singular, full_name_plural, short_name, description, unit_property, } => { query!( " INSERT INTO units (id, unit_property, full_name_singular, full_name_plural, short_name, description) VALUES (?,?,?,?,?,?) ", id, unit_property, full_name_singular, full_name_plural, short_name, description, ) .execute(txn) .await?; } } Ok(()) } async fn undo(self, txn: &mut sqlx::SqliteConnection) -> Result<(), undo::Error> { match self { Operation::RegisterUnit { id, full_name_singular, full_name_plural, short_name, description, unit_property, } => { query!( " DELETE FROM units WHERE id = ? AND full_name_singular = ? AND full_name_plural = ? AND short_name = ? AND description = ? AND unit_property = ?; ", id, full_name_singular, full_name_plural, short_name, description, unit_property ) .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 Unit { pub(crate) fn register( full_name_singular: String, full_name_plural: String, short_name: String, description: Option, unit_property: UnitPropertyId, ops: &mut Operations, ) -> Self { let id = UnitId::from(Uuid::new_v4()); ops.push(Operation::RegisterUnit { id, full_name_singular: full_name_singular.clone(), full_name_plural: full_name_plural.clone(), short_name: short_name.clone(), description: description.clone(), unit_property, }); Self { id, full_name_singular, full_name_plural, short_name, description, unit_property, } } }