diff --git a/rust/sqlx-data.json b/rust/sqlx-data.json index fc06534..6022e6c 100644 --- a/rust/sqlx-data.json +++ b/rust/sqlx-data.json @@ -140,48 +140,6 @@ }, "query": "DELETE FROM inventory_items\n WHERE id = ?" }, - "53c45b9447118c8b448df6836e68a38ff78d0b7f4d5344a1e5064d31e70396b3": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "name", - "ordinal": 1, - "type_info": "Text" - }, - { - "name": "weight", - "ordinal": 2, - "type_info": "Int64" - }, - { - "name": "description", - "ordinal": 3, - "type_info": "Text" - }, - { - "name": "category_id", - "ordinal": 4, - "type_info": "Text" - } - ], - "nullable": [ - false, - false, - false, - true, - false - ], - "parameters": { - "Right": 1 - } - }, - "query": "SELECT\n id,\n name,\n weight,\n description,\n category_id\n FROM inventory_items AS item\n WHERE item.id = ?" - }, "5fd2b986fcaafe93e816f9ed665b6319d120a3987dc5adca1e3c8634203f7533": { "describe": { "columns": [ diff --git a/rust/src/main.rs b/rust/src/main.rs index cae3287..d436936 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -674,7 +674,7 @@ async fn trip_row( let item_row = view::trip::TripItemListRow::build( trip_id, &item, - models::inventory::Item::get_category_max_weight( + models::inventory::InventoryItem::get_category_max_weight( &state.database_pool, item.item.category_id, ) diff --git a/rust/src/models/inventory.rs b/rust/src/models/inventory.rs index 792b772..7b7adc8 100644 --- a/rust/src/models/inventory.rs +++ b/rust/src/models/inventory.rs @@ -137,7 +137,7 @@ pub struct Product { pub comment: Option, } -pub struct inventoryItem { +pub struct InventoryItem { pub id: Uuid, pub name: String, pub description: Option, @@ -300,6 +300,7 @@ impl InventoryItem { Ok(id) } + pub async fn get_category_max_weight( pool: &sqlx::Pool, category_id: Uuid, @@ -329,84 +330,64 @@ impl InventoryItem { } } -// #[derive(Debug)] -// pub struct Item { -// pub id: Uuid, -// pub name: String, -// pub description: Option, -// pub weight: i64, -// pub category_id: Uuid, -// } +#[derive(Debug)] +pub struct Item { + pub id: Uuid, + pub name: String, + pub description: Option, + pub weight: i64, + pub category_id: Uuid, +} -// pub struct DbInventoryItemsRow { -// pub id: String, -// pub name: String, -// pub weight: i64, -// pub description: Option, -// pub category_id: String, -// } +pub struct DbInventoryItemsRow { + pub id: String, + pub name: String, + pub weight: i64, + pub description: Option, + pub category_id: String, +} -// impl TryFrom for Item { -// type Error = Error; +impl TryFrom for Item { + type Error = Error; -// fn try_from(row: DbInventoryItemsRow) -> Result { -// Ok(Item { -// id: Uuid::try_parse(&row.id)?, -// name: row.name, -// description: row.description, // TODO -// weight: row.weight, -// category_id: Uuid::try_parse(&row.category_id)?, -// }) -// } -// } + fn try_from(row: DbInventoryItemsRow) -> Result { + Ok(Item { + id: Uuid::try_parse(&row.id)?, + name: row.name, + description: row.description, // TODO + weight: row.weight, + category_id: Uuid::try_parse(&row.category_id)?, + }) + } +} -// impl Item { -// pub async fn find(pool: &sqlx::Pool, id: Uuid) -> Result, Error> { -// let id_param = id.to_string(); -// sqlx::query_as!( -// DbInventoryItemsRow, -// "SELECT -// id, -// name, -// weight, -// description, -// category_id -// FROM inventory_items AS item -// WHERE item.id = ?", -// id_param, -// ) -// .fetch_optional(pool) -// .await? -// .map(|row| row.try_into()) -// .transpose() -// } - -// pub async fn _get_category_total_picked_weight( -// pool: &sqlx::Pool, -// category_id: Uuid, -// ) -> Result { -// let category_id_param = category_id.to_string(); -// Ok(sqlx::query!( -// " -// SELECT COALESCE(SUM(i_item.weight), 0) as weight -// FROM inventory_items_categories as category -// INNER JOIN inventory_items as i_item -// ON i_item.category_id = category.id -// INNER JOIN trips_items as t_item -// ON i_item.id = t_item.item_id -// WHERE category_id = ? -// AND t_item.pick = 1 -// ", -// category_id_param -// ) -// .fetch_one(pool) -// .map_ok(|row| { -// // convert to i64 because that the default integer type, but looks -// // like COALESCE return i32? -// // -// // We can be certain that the row exists, as we COALESCE it -// row.weight.unwrap() as i64 -// }) -// .await?) -// } -// } +impl Item { + pub async fn _get_category_total_picked_weight( + pool: &sqlx::Pool, + category_id: Uuid, + ) -> Result { + let category_id_param = category_id.to_string(); + Ok(sqlx::query!( + " + SELECT COALESCE(SUM(i_item.weight), 0) as weight + FROM inventory_items_categories as category + INNER JOIN inventory_items as i_item + ON i_item.category_id = category.id + INNER JOIN trips_items as t_item + ON i_item.id = t_item.item_id + WHERE category_id = ? + AND t_item.pick = 1 + ", + category_id_param + ) + .fetch_one(pool) + .map_ok(|row| { + // convert to i64 because that the default integer type, but looks + // like COALESCE return i32? + // + // We can be certain that the row exists, as we COALESCE it + row.weight.unwrap() as i64 + }) + .await?) + } +} diff --git a/rust/src/out b/rust/src/out new file mode 100644 index 0000000..f0df2d4 --- /dev/null +++ b/rust/src/out @@ -0,0 +1,138 @@ +pub struct InventoryItem { + pub id: Uuid, + pub name: String, + pub description: Option, + pub weight: i64, + pub category: Category, + pub product: Option, +} + +struct DbInventoryItemRow { + pub id: String, + pub name: String, + pub description: Option, + pub weight: i64, + pub category_id: String, + pub category_name: String, + pub category_description: Option, + pub product_id: Option, + pub product_name: Option, + pub product_description: Option, + pub product_comment: Option, +} + +impl TryFrom for InventoryItem { + type Error = Error; + + fn try_from(row: DbInventoryItemRow) -> Result { + Ok(InventoryItem { + id: Uuid::try_parse(&row.id)?, + name: row.name, + description: row.description, + weight: row.weight, + category: Category { + id: Uuid::try_parse(&row.category_id)?, + name: row.category_name, + description: row.category_description, + items: None, + }, + product: row + .product_id + .map(|id| -> Result { + Ok(Product { + id: Uuid::try_parse(&id)?, + name: row.product_name.unwrap(), + description: row.product_description, + comment: row.product_comment, + }) + }) + .transpose()?, + }) + } +} + +impl InventoryItem { + pub async fn find(pool: &sqlx::Pool, id: Uuid) -> Result, Error> { + let id_param = id.to_string(); + + sqlx::query_as!( + DbInventoryItemRow, + "SELECT + item.id AS id, + item.name AS name, + item.description AS description, + weight, + category.id AS category_id, + category.name AS category_name, + category.description AS category_description, + product.id AS product_id, + product.name AS product_name, + product.description AS product_description, + product.comment AS product_comment + FROM inventory_items AS item + INNER JOIN inventory_items_categories as category + ON item.category_id = category.id + LEFT JOIN inventory_products AS product + ON item.product_id = product.id + WHERE item.id = ?", + id_param, + ) + .fetch_optional(pool) + .await? + .map(|row| row.try_into()) + .transpose() + } + + pub async fn name_exists(pool: &sqlx::Pool, name: &str) -> Result { + Ok(sqlx::query!( + "SELECT id + FROM inventory_items + WHERE name = ?", + name, + ) + .fetch_optional(pool) + .await? + .map(|_row| ()) + .is_some()) + } + + pub async fn delete(pool: &sqlx::Pool, id: Uuid) -> Result { + let id_param = id.to_string(); + let results = sqlx::query!( + "DELETE FROM inventory_items + WHERE id = ?", + id_param + ) + .execute(pool) + .await?; + + Ok(results.rows_affected() != 0) + } + + pub async fn save( + pool: &sqlx::Pool, + name: &str, + category_id: Uuid, + weight: u32, + ) -> Result { + let id = Uuid::new_v4(); + let id_param = id.to_string(); + let category_id_param = category_id.to_string(); + + sqlx::query!( + "INSERT INTO inventory_items + (id, name, description, weight, category_id) + VALUES + (?, ?, ?, ?, ?)", + id_param, + name, + "", + weight, + category_id_param + ) + .execute(pool) + .await?; + + Ok(id) + } +}