feat: add deleted flag to Store aggregate & ignore deleted stores while checking store name uniqueness #38
4 changed files with 34 additions and 37 deletions
|
@ -29,13 +29,30 @@ impl StoreIDExistsDBPort for InventoryDBPostgresAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
pub mod tests {
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::utils::uuid::tests::UUID;
|
use crate::utils::uuid::tests::UUID;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
pub async fn create_dummy_store_record(s: &Store, db: &InventoryDBPostgresAdapter) {
|
||||||
|
sqlx::query!(
|
||||||
|
"INSERT INTO cqrs_inventory_store_query
|
||||||
|
(version, name, address, store_id, owner, deleted)
|
||||||
|
VALUES ($1, $2, $3, $4, $5 ,$6);",
|
||||||
|
1,
|
||||||
|
s.name(),
|
||||||
|
s.address().as_ref().unwrap(),
|
||||||
|
s.store_id(),
|
||||||
|
s.owner(),
|
||||||
|
false
|
||||||
|
)
|
||||||
|
.execute(&db.pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_postgres_store_exists() {
|
async fn test_postgres_store_exists() {
|
||||||
let store_id = Uuid::new_v4();
|
let store_id = Uuid::new_v4();
|
||||||
|
@ -58,19 +75,7 @@ mod tests {
|
||||||
// state doesn't exist
|
// state doesn't exist
|
||||||
assert!(!db.store_id_exists(&store).await.unwrap());
|
assert!(!db.store_id_exists(&store).await.unwrap());
|
||||||
|
|
||||||
sqlx::query!(
|
create_dummy_store_record(&store, &db).await;
|
||||||
"INSERT INTO cqrs_inventory_store_query
|
|
||||||
(version, name, address, store_id, owner)
|
|
||||||
VALUES ($1, $2, $3, $4, $5);",
|
|
||||||
1,
|
|
||||||
store.name(),
|
|
||||||
store.address().as_ref().unwrap(),
|
|
||||||
store.store_id(),
|
|
||||||
store.owner(),
|
|
||||||
)
|
|
||||||
.execute(&db.pool)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// state exists
|
// state exists
|
||||||
assert!(db.store_id_exists(&store).await.unwrap());
|
assert!(db.store_id_exists(&store).await.unwrap());
|
||||||
|
|
|
@ -35,6 +35,7 @@ mod tests {
|
||||||
use crate::utils::uuid::tests::UUID;
|
use crate::utils::uuid::tests::UUID;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::inventory::adapters::output::db::postgres::store_id_exists::tests::create_dummy_store_record;
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_postgres_store_exists() {
|
async fn test_postgres_store_exists() {
|
||||||
|
@ -58,19 +59,7 @@ mod tests {
|
||||||
// state doesn't exist
|
// state doesn't exist
|
||||||
assert!(!db.store_name_exists(&store).await.unwrap());
|
assert!(!db.store_name_exists(&store).await.unwrap());
|
||||||
|
|
||||||
sqlx::query!(
|
create_dummy_store_record(&store, &db).await;
|
||||||
"INSERT INTO cqrs_inventory_store_query
|
|
||||||
(version, name, address, store_id, owner)
|
|
||||||
VALUES ($1, $2, $3, $4, $5);",
|
|
||||||
1,
|
|
||||||
store.name(),
|
|
||||||
store.address().as_ref().unwrap(),
|
|
||||||
store.store_id(),
|
|
||||||
store.owner(),
|
|
||||||
)
|
|
||||||
.execute(&db.pool)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// state exists
|
// state exists
|
||||||
assert!(db.store_name_exists(&store).await.unwrap());
|
assert!(db.store_name_exists(&store).await.unwrap());
|
||||||
|
|
|
@ -24,6 +24,7 @@ pub struct StoreView {
|
||||||
address: Option<String>,
|
address: Option<String>,
|
||||||
store_id: Uuid,
|
store_id: Uuid,
|
||||||
owner: Uuid,
|
owner: Uuid,
|
||||||
|
deleted: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
// This updates the view with events as they are committed.
|
// This updates the view with events as they are committed.
|
||||||
|
@ -37,6 +38,7 @@ impl View<Store> for StoreView {
|
||||||
self.address = val.address().clone();
|
self.address = val.address().clone();
|
||||||
self.store_id = val.store_id().clone();
|
self.store_id = val.store_id().clone();
|
||||||
self.owner = val.owner().clone();
|
self.owner = val.owner().clone();
|
||||||
|
self.deleted = false;
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
@ -54,7 +56,7 @@ impl ViewRepository<StoreView, Store> for InventoryDBPostgresAdapter {
|
||||||
let res = sqlx::query_as!(
|
let res = sqlx::query_as!(
|
||||||
StoreView,
|
StoreView,
|
||||||
"SELECT
|
"SELECT
|
||||||
name, address, store_id, owner
|
name, address, store_id, owner, deleted
|
||||||
FROM
|
FROM
|
||||||
cqrs_inventory_store_query
|
cqrs_inventory_store_query
|
||||||
WHERE
|
WHERE
|
||||||
|
@ -79,7 +81,7 @@ impl ViewRepository<StoreView, Store> for InventoryDBPostgresAdapter {
|
||||||
let res = sqlx::query_as!(
|
let res = sqlx::query_as!(
|
||||||
StoreView,
|
StoreView,
|
||||||
"SELECT
|
"SELECT
|
||||||
name, address, store_id, owner
|
name, address, store_id, owner, deleted
|
||||||
FROM
|
FROM
|
||||||
cqrs_inventory_store_query
|
cqrs_inventory_store_query
|
||||||
WHERE
|
WHERE
|
||||||
|
@ -123,15 +125,16 @@ impl ViewRepository<StoreView, Store> for InventoryDBPostgresAdapter {
|
||||||
let version = context.version + 1;
|
let version = context.version + 1;
|
||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
"INSERT INTO cqrs_inventory_store_query (
|
"INSERT INTO cqrs_inventory_store_query (
|
||||||
version, name, address, store_id, owner
|
version, name, address, store_id, owner, deleted
|
||||||
) VALUES (
|
) VALUES (
|
||||||
$1, $2, $3, $4, $5
|
$1, $2, $3, $4, $5, $6
|
||||||
);",
|
);",
|
||||||
version,
|
version,
|
||||||
view.name,
|
view.name,
|
||||||
view.address,
|
view.address,
|
||||||
view.store_id,
|
view.store_id,
|
||||||
view.owner,
|
view.owner,
|
||||||
|
view.deleted,
|
||||||
)
|
)
|
||||||
.execute(&self.pool)
|
.execute(&self.pool)
|
||||||
.await
|
.await
|
||||||
|
@ -147,12 +150,14 @@ impl ViewRepository<StoreView, Store> for InventoryDBPostgresAdapter {
|
||||||
name = $2,
|
name = $2,
|
||||||
address = $3,
|
address = $3,
|
||||||
store_id = $4,
|
store_id = $4,
|
||||||
owner = $5;",
|
owner = $5,
|
||||||
|
deleted = $6;",
|
||||||
version,
|
version,
|
||||||
view.name,
|
view.name,
|
||||||
view.address,
|
view.address,
|
||||||
view.store_id,
|
view.store_id,
|
||||||
view.owner,
|
view.owner,
|
||||||
|
view.deleted,
|
||||||
)
|
)
|
||||||
.execute(&self.pool)
|
.execute(&self.pool)
|
||||||
.await
|
.await
|
||||||
|
|
|
@ -22,6 +22,8 @@ pub struct Store {
|
||||||
address: Option<String>,
|
address: Option<String>,
|
||||||
owner: Uuid,
|
owner: Uuid,
|
||||||
store_id: Uuid,
|
store_id: Uuid,
|
||||||
|
#[builder(default = "false")]
|
||||||
|
deleted: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
|
@ -49,11 +51,6 @@ impl Aggregate for Store {
|
||||||
Ok(vec![InventoryEvent::StoreAdded(res)])
|
Ok(vec![InventoryEvent::StoreAdded(res)])
|
||||||
}
|
}
|
||||||
_ => Ok(Vec::default()),
|
_ => Ok(Vec::default()),
|
||||||
// InventoryCommand::AddCategory(cmd) => {
|
|
||||||
// let res = services.add_category().add_store(cmd).await?;
|
|
||||||
// Ok(vec![InventoryEvent::CategoryAdded(res)])
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +61,7 @@ impl Aggregate for Store {
|
||||||
self.address = e.address().as_ref().map(|s| s.to_string());
|
self.address = e.address().as_ref().map(|s| s.to_string());
|
||||||
self.owner = e.owner().clone();
|
self.owner = e.owner().clone();
|
||||||
self.store_id = e.store_id().clone();
|
self.store_id = e.store_id().clone();
|
||||||
|
self.deleted = false;
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue