wb_cache/test/simulation/db/entity/
product.rs

1use std::fmt::Debug;
2use std::sync::Arc;
3
4use crate::test::simulation::db::cache::CacheUpdates;
5use crate::test::simulation::db::cache::DBProvider;
6use crate::test::simulation::db::cache::DCCommon;
7use crate::test::simulation::types::Result;
8use crate::test::simulation::types::SimErrorAny;
9use crate::types::DataControllerResponse;
10use crate::update_iterator::UpdateIterator;
11use crate::DataController;
12
13use async_trait::async_trait;
14use fieldx_plus::fx_plus;
15use sea_orm::entity::prelude::*;
16use sea_orm::IntoActiveModel;
17use serde::Deserialize;
18use serde::Serialize;
19use tracing::debug;
20
21#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
22#[sea_orm(table_name = "products")]
23#[serde(deny_unknown_fields)]
24pub struct Model {
25    #[sea_orm(primary_key, auto_increment = false)]
26    #[serde(rename = "i")]
27    pub id:    i32,
28    #[serde(rename = "n")]
29    pub name:  String,
30    #[serde(rename = "p")]
31    pub price: f64,
32    /// How many views the product listing has received.
33    #[serde(rename = "v")]
34    pub views: i64,
35}
36
37#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
38pub enum Relation {}
39
40impl ActiveModelBehavior for ActiveModel {}
41
42// The manager and data controller for the product model.
43#[fx_plus(
44    child(DBCP, unwrap(or_else(SimErrorAny, super::dbcp_gone("product manager")))),
45    sync,
46    rc
47)]
48pub struct Manager<DBCP>
49where
50    DBCP: DBProvider, {}
51
52impl<DBCP> Manager<DBCP>
53where
54    DBCP: DBProvider,
55{
56    /// Get product by its ID.
57    pub async fn get_by_product_id(&self, product_id: i32) -> Result<Vec<Model>> {
58        debug!("Fetching product with ID: {}", product_id);
59        Ok(Entity::find()
60            .filter(Column::Id.eq(product_id))
61            .all(&self.db_provider()?.db_connection()?)
62            .await?)
63    }
64}
65
66impl<DBCP> Debug for Manager<DBCP>
67where
68    DBCP: DBProvider,
69{
70    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71        write!(f, "ProductManager")
72    }
73}
74
75#[async_trait]
76impl<DBCP> DataController for Manager<DBCP>
77where
78    DBCP: DBProvider,
79{
80    type CacheUpdate = CacheUpdates<ActiveModel>;
81    type Error = SimErrorAny;
82    type Key = i32;
83    type Value = Model;
84
85    async fn get_for_key(&self, id: &Self::Key) -> Result<Option<Self::Value>> {
86        Ok(Entity::find_by_id(*id)
87            .one(&self.db_provider()?.db_connection()?)
88            .await?)
89    }
90
91    fn primary_key_of(&self, value: &Self::Value) -> Self::Key {
92        value.id
93    }
94
95    async fn write_back(&self, update_records: Arc<UpdateIterator<Self>>) -> Result<(), Self::Error> {
96        self.wbdc_write_back(update_records).await
97    }
98
99    async fn on_new(&self, key: &Self::Key, value: &Self::Value) -> Result<DataControllerResponse<Self>, Self::Error> {
100        self.wbdbc_on_new(key, &value.clone().into_active_model()).await
101    }
102
103    async fn on_delete(
104        &self,
105        key: &Self::Key,
106        update: Option<&CacheUpdates<ActiveModel>>,
107    ) -> Result<DataControllerResponse<Self>> {
108        self.wbdc_on_delete(key, update).await
109    }
110
111    async fn on_change(
112        &self,
113        key: &Self::Key,
114        value: &Self::Value,
115        old_value: Self::Value,
116        prev_update: Option<Self::CacheUpdate>,
117    ) -> Result<DataControllerResponse<Self>> {
118        self.wbdc_on_change(key, value, old_value, prev_update).await
119    }
120}
121
122impl<DBCP> DCCommon<Entity, DBCP, true> for Manager<DBCP>
123where
124    DBCP: DBProvider,
125{
126    fn delete_many_condition(dm: sea_orm::DeleteMany<Entity>, keys: Vec<Self::Key>) -> sea_orm::DeleteMany<Entity> {
127        dm.filter(Column::Id.is_in(keys))
128    }
129}