backbone_catalog/infrastructure/persistence/
brand_repository.rs1use sqlx::PgPool;
16use uuid::Uuid;
17
18use crate::domain::entity::Brand;
19
20pub const TABLE_NAME: &str = "catalog.brands";
22
23pub struct BrandRepository(
28 backbone_orm::GenericCrudRepository<Brand, backbone_orm::SoftDelete>,
29);
30
31impl std::ops::Deref for BrandRepository {
32 type Target = backbone_orm::GenericCrudRepository<Brand, backbone_orm::SoftDelete>;
33 fn deref(&self) -> &Self::Target { &self.0 }
34}
35
36impl BrandRepository {
37 pub fn new(pool: PgPool) -> Self {
39 Self(backbone_orm::GenericCrudRepository::new(pool, TABLE_NAME))
40 }
41}
42
43pub struct NewBrandRow<'a> {
45 pub id: Uuid,
46 pub code: &'a str,
47 pub name: &'a str,
48 pub short_description: Option<&'a str>,
49 pub description: Option<&'a str>,
50 pub logo_url: Option<&'a str>,
51 pub sort_order: i32,
52}
53
54impl BrandRepository {
56 pub async fn exists_id(&self, executor: impl sqlx::Executor<'_, Database = sqlx::Postgres>, id: Uuid) -> Result<bool, sqlx::Error> {
59 let found: Option<Uuid> = sqlx::query_scalar(
60 "SELECT id FROM catalog.brands \
61 WHERE id = $1 AND (metadata->>'deleted_at') IS NULL",
62 )
63 .bind(id)
64 .fetch_optional(executor)
65 .await?;
66 Ok(found.is_some())
67 }
68
69 pub async fn insert_brand(
72 &self,
73 executor: impl sqlx::Executor<'_, Database = sqlx::Postgres>,
74 r: &NewBrandRow<'_>,
75 ) -> Result<(), sqlx::Error> {
76 sqlx::query(
77 r#"INSERT INTO catalog.brands
78 (id, code, name, short_description, description, logo_url, sort_order, status)
79 VALUES ($1,$2,$3,$4,$5,$6,$7,'active'::catalog_status)"#,
80 )
81 .bind(r.id)
82 .bind(r.code)
83 .bind(r.name)
84 .bind(r.short_description)
85 .bind(r.description)
86 .bind(r.logo_url)
87 .bind(r.sort_order)
88 .execute(executor)
89 .await?;
90 Ok(())
91 }
92}
93
94backbone_core::impl_crud_repository!(BrandRepository, Brand, soft_delete);