From 07c3c6c56d83f4cf63897473839a1ac41a3c5e21 Mon Sep 17 00:00:00 2001 From: Aravinth Manivannan Date: Mon, 15 Jul 2024 17:53:53 +0530 Subject: [PATCH] feat: impl product ID exists DB port --- .../adapters/output/db/postgres/mod.rs | 3 + .../output/db/postgres/product_id_exists.rs | 103 ++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 src/inventory/adapters/output/db/postgres/product_id_exists.rs diff --git a/src/inventory/adapters/output/db/postgres/mod.rs b/src/inventory/adapters/output/db/postgres/mod.rs index 7baaec0..9c106f3 100644 --- a/src/inventory/adapters/output/db/postgres/mod.rs +++ b/src/inventory/adapters/output/db/postgres/mod.rs @@ -12,6 +12,9 @@ mod category_id_exists; mod category_name_exists_for_store; mod category_view; mod errors; +mod product_id_exists; +mod product_name_exists_for_category; +mod product_view; mod store_id_exists; mod store_name_exists; mod store_view; diff --git a/src/inventory/adapters/output/db/postgres/product_id_exists.rs b/src/inventory/adapters/output/db/postgres/product_id_exists.rs new file mode 100644 index 0000000..9d8b076 --- /dev/null +++ b/src/inventory/adapters/output/db/postgres/product_id_exists.rs @@ -0,0 +1,103 @@ +// SPDX-FileCopyrightText: 2024 Aravinth Manivannan +// +// SPDX-License-Identifier: AGPL-3.0-or-later +use uuid::Uuid; + +use super::InventoryDBPostgresAdapter; +use crate::inventory::application::port::output::db::{errors::*, product_id_exists::*}; + +#[async_trait::async_trait] +impl ProductIDExistsDBPort for InventoryDBPostgresAdapter { + async fn product_id_exists(&self, product_id: &Uuid) -> InventoryDBResult { + let res = sqlx::query!( + "SELECT EXISTS ( + SELECT 1 + FROM cqrs_inventory_product_query + WHERE + product_id = $1 + );", + product_id + ) + .fetch_one(&self.pool) + .await?; + if let Some(x) = res.exists { + Ok(x) + } else { + Ok(false) + } + } +} + +#[cfg(test)] +pub mod tests { + + use super::*; + use crate::inventory::domain::{add_product_command::tests::get_command, product_aggregate::*}; + use crate::utils::uuid::tests::UUID; + + #[actix_rt::test] + async fn test_postgres_product_exists() { + let settings = crate::settings::tests::get_settings().await; + settings.create_db().await; + let db = super::InventoryDBPostgresAdapter::new( + sqlx::postgres::PgPool::connect(&settings.database.url) + .await + .unwrap(), + ); + + let cmd = get_command(); + + let product = ProductBuilder::default() + .name(cmd.name().into()) + .description(cmd.description().as_ref().map(|s| s.to_string())) + .image(cmd.image().as_ref().map(|s| s.to_string())) + .sku_able(cmd.sku_able().clone()) + .category_id(cmd.category_id().clone()) + .product_id(UUID.clone()) + .price(cmd.price().clone()) + .build() + .unwrap(); + + // state doesn't exist + assert!(!db.product_id_exists(product.product_id()).await.unwrap()); + + create_dummy_product_record(&product, &db).await; + + // state exists + assert!(db.product_id_exists(product.product_id()).await.unwrap()); + + settings.drop_db().await; + } + + pub async fn create_dummy_product_record(p: &Product, db: &InventoryDBPostgresAdapter) { + sqlx::query!( + "INSERT INTO cqrs_inventory_product_query ( + version, + name, + description, + image, + product_id, + category_id, + price_major, + price_minor, + price_currency, + sku_able + ) VALUES ( + $1, $2, $3, $4, $5, $6, $7, $8, $9, $10 + );", + 1, + p.name(), + p.description().as_ref().unwrap(), + p.image().as_ref().unwrap(), + p.product_id(), + p.category_id(), + p.price().major().clone() as i32, + p.price().minor().clone() as i32, + p.price().currency().to_string(), + p.sku_able().clone() + ) + .execute(&db.pool) + .await + .unwrap(); + } +}