wb_cache/test/simulation/db/entity/
customer.rs1use async_trait::async_trait;
2use fieldx_plus::fx_plus;
3use sea_orm::entity::prelude::*;
4use sea_orm::Condition;
5use sea_orm::DeleteMany;
6use sea_orm::IntoActiveModel;
7use sea_orm::QuerySelect;
8use serde::Deserialize;
9use serde::Serialize;
10
11use std::fmt::Debug;
12use std::fmt::Display;
13use std::sync::Arc;
14
15use crate::test::simulation::db::cache::CacheUpdates;
16use crate::test::simulation::db::cache::DBProvider;
17use crate::test::simulation::db::cache::DCCommon;
18use crate::test::simulation::types::Result;
19use crate::test::simulation::types::SimErrorAny;
20use crate::types::DataControllerResponse;
21use crate::update_iterator::UpdateIterator;
22use crate::DataController;
23
24#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
25#[sea_orm(table_name = "customers")]
26#[serde(deny_unknown_fields)]
27pub struct Model {
28 #[sea_orm(primary_key)]
29 #[serde(rename = "i")]
30 pub id: i32,
31 #[sea_orm(unique, indexed)]
32 #[serde(rename = "e")]
33 pub email: String,
34 #[serde(rename = "f")]
35 pub first_name: String,
36 #[serde(rename = "l")]
37 pub last_name: String,
38 #[serde(rename = "d")]
40 pub registered_on: i32,
41}
42
43#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
44pub enum Relation {}
45
46impl ActiveModelBehavior for ActiveModel {}
47
48#[derive(Clone, Debug, PartialEq, Eq, Hash)]
50pub enum CustomerBy {
51 Id(i32),
53 Email(String),
55}
56
57impl Display for CustomerBy {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59 match self {
60 CustomerBy::Id(id) => write!(f, "#{id}"),
61 CustomerBy::Email(email) => write!(f, "{email}"),
62 }
63 }
64}
65
66#[fx_plus(
68 child(DBCP, unwrap(or_else(SimErrorAny, super::dbcp_gone("customer manager")))),
69 sync,
70 rc
71)]
72pub struct Manager<DBCP>
73where
74 DBCP: DBProvider, {}
75
76impl<DBCP> Manager<DBCP>
77where
78 DBCP: DBProvider,
79{
80 pub async fn get_by_id(&self, id: i32) -> Result<Option<Model>> {
82 let parent = self.parent()?;
83 let db = parent.db_connection()?;
84 Ok(Entity::find_by_id(id).one(&db).await?)
85 }
86
87 pub async fn get_by_email(&self, email: &str) -> Result<Option<Model>> {
89 let parent = self.parent()?;
90 let db = parent.db_connection()?;
91 Ok(Entity::find().filter(Column::Email.eq(email)).one(&db).await?)
92 }
93}
94
95impl<DBCP> Debug for Manager<DBCP>
96where
97 DBCP: DBProvider,
98{
99 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100 write!(f, "CustomerManager")
101 }
102}
103
104#[async_trait]
105impl<DBCP> DataController for Manager<DBCP>
106where
107 DBCP: DBProvider,
108{
109 type CacheUpdate = CacheUpdates<ActiveModel>;
110 type Error = SimErrorAny;
111 type Key = CustomerBy;
112 type Value = Model;
113
114 async fn get_for_key(&self, key: &Self::Key) -> Result<Option<Self::Value>> {
115 Ok(match key {
116 CustomerBy::Id(id) => self.get_by_id(*id).await?,
117 CustomerBy::Email(email) => self.get_by_email(email).await?,
118 })
119 }
120
121 async fn get_primary_key_for(&self, key: &Self::Key) -> Result<Option<Self::Key>> {
122 Ok(match key {
123 CustomerBy::Id(_) => Some(key.clone()),
124 CustomerBy::Email(email) => Entity::find()
126 .filter(Column::Email.eq(email))
127 .select_only()
128 .column(Column::Id)
129 .into_tuple::<i32>()
130 .one(&self.parent()?.db_connection()?)
131 .await?
132 .map(CustomerBy::Id),
133 })
134 }
135
136 fn primary_key_of(&self, value: &Self::Value) -> Self::Key {
137 CustomerBy::Id(value.id)
138 }
139
140 fn secondary_keys_of(&self, value: &Self::Value) -> Vec<Self::Key> {
141 vec![CustomerBy::Email(value.email.clone())]
142 }
143
144 fn is_primary(&self, key: &Self::Key) -> bool {
146 matches!(key, CustomerBy::Id(_))
147 }
148
149 async fn write_back(&self, update_records: Arc<UpdateIterator<Self>>) -> Result<()> {
150 self.wbdc_write_back(update_records).await
151 }
152
153 async fn on_new(&self, key: &Self::Key, value: &Self::Value) -> Result<DataControllerResponse<Self>, Self::Error> {
154 self.wbdbc_on_new(key, &value.clone().into_active_model()).await
155 }
156
157 async fn on_delete(
158 &self,
159 key: &Self::Key,
160 update: Option<&CacheUpdates<ActiveModel>>,
161 ) -> Result<DataControllerResponse<Self>> {
162 self.wbdc_on_delete(key, update).await
163 }
164
165 async fn on_change(
166 &self,
167 key: &Self::Key,
168 value: &Self::Value,
169 old_value: Self::Value,
170 prev_update: Option<Self::CacheUpdate>,
171 ) -> Result<DataControllerResponse<Self>> {
172 self.wbdc_on_change(key, value, old_value, prev_update).await
173 }
174}
175
176#[async_trait]
177impl<DBCP> DCCommon<Entity, DBCP> for Manager<DBCP>
178where
179 DBCP: DBProvider,
180{
181 fn delete_many_condition(dm: DeleteMany<Entity>, keys: Vec<Self::Key>) -> DeleteMany<Entity> {
184 let mut by_id = vec![];
185 let mut by_email = vec![];
186 for key in keys {
187 match key {
188 CustomerBy::Id(id) => by_id.push(id),
189 CustomerBy::Email(email) => by_email.push(email),
190 }
191 }
192
193 let mut condition = Condition::any();
194
195 if !by_id.is_empty() {
196 condition = condition.add(Column::Id.is_in(by_id));
197 }
198 if !by_email.is_empty() {
199 condition = condition.add(Column::Email.is_in(by_email));
200 }
201
202 dm.filter(condition)
203 }
204}