backend/model/entity/
areas_impl.rs1use chrono::NaiveDate;
4use diesel::{
5 debug_query, pg::Pg, BoolExpressionMethods, ExpressionMethods, QueryDsl, QueryResult,
6};
7use diesel_async::{AsyncConnection, AsyncPgConnection, RunQueryDsl};
8use log::debug;
9use uuid::Uuid;
10
11use crate::{
12 model::{
13 dto::areas::{AreaDto, AreaKind},
14 entity::areas::{
15 Hydrology, Shading, SoilTexture, UpdateHydrology, UpdateShading, UpdateSoilTexture,
16 },
17 },
18 schema::{hydrologies, shadings, soil_textures},
19};
20
21pub struct FindAreaParameters {
23 pub area_kind: AreaKind,
25 pub layer_id: Option<Uuid>,
27 pub from: NaiveDate,
29 pub to: NaiveDate,
31}
32
33pub async fn find_area(
38 search_parameters: FindAreaParameters,
39 conn: &mut AsyncPgConnection,
40) -> QueryResult<Vec<AreaDto>> {
41 match search_parameters.area_kind {
42 AreaKind::Shade => {
43 let mut query = shadings::table.select(shadings::all_columns).into_boxed();
44
45 if let Some(id) = search_parameters.layer_id {
46 query = query.filter(shadings::layer_id.eq(id));
47 }
48
49 let added_before_date = shadings::add_date
50 .is_null()
51 .or(shadings::add_date.lt(search_parameters.to));
52 let removed_after_date = shadings::remove_date
53 .is_null()
54 .or(shadings::remove_date.gt(search_parameters.from));
55 query = query.filter(added_before_date.and(removed_after_date));
56
57 debug!("{}", debug_query::<Pg, _>(&query));
58
59 Ok(query
60 .load::<Shading>(conn)
61 .await?
62 .into_iter()
63 .map(Into::into)
64 .collect())
65 }
66 AreaKind::Hydrology => {
67 let mut query = hydrologies::table
68 .select(hydrologies::all_columns)
69 .into_boxed();
70
71 if let Some(id) = search_parameters.layer_id {
72 query = query.filter(hydrologies::layer_id.eq(id));
73 }
74
75 let added_before_date = hydrologies::add_date
76 .is_null()
77 .or(hydrologies::add_date.lt(search_parameters.to));
78 let removed_after_date = hydrologies::remove_date
79 .is_null()
80 .or(hydrologies::remove_date.gt(search_parameters.from));
81 query = query.filter(added_before_date.and(removed_after_date));
82
83 debug!("{}", debug_query::<Pg, _>(&query));
84
85 Ok(query
86 .load::<Hydrology>(conn)
87 .await?
88 .into_iter()
89 .map(Into::into)
90 .collect())
91 }
92 AreaKind::SoilTexture => {
93 let mut query = soil_textures::table
94 .select(soil_textures::all_columns)
95 .into_boxed();
96
97 if let Some(id) = search_parameters.layer_id {
98 query = query.filter(soil_textures::layer_id.eq(id));
99 }
100
101 let added_before_date = soil_textures::add_date
102 .is_null()
103 .or(soil_textures::add_date.lt(search_parameters.to));
104 let removed_after_date = soil_textures::remove_date
105 .is_null()
106 .or(soil_textures::remove_date.gt(search_parameters.from));
107 query = query.filter(added_before_date.and(removed_after_date));
108
109 debug!("{}", debug_query::<Pg, _>(&query));
110
111 Ok(query
112 .load::<SoilTexture>(conn)
113 .await?
114 .into_iter()
115 .map(Into::into)
116 .collect())
117 }
118 }
119}
120
121pub async fn create_shadings(
126 new_shadings: Vec<Shading>,
127 conn: &mut AsyncPgConnection,
128) -> QueryResult<Vec<AreaDto>> {
129 let query = diesel::insert_into(shadings::table).values(&new_shadings);
130 debug!("{}", debug_query::<Pg, _>(&query));
131 let shadings = query
132 .get_results::<Shading>(conn)
133 .await?
134 .into_iter()
135 .map(Into::into)
136 .collect::<Vec<AreaDto>>();
137 Ok(shadings)
138}
139
140pub async fn create_hydrologies(
145 new_hydrologies: Vec<Hydrology>,
146 conn: &mut AsyncPgConnection,
147) -> QueryResult<Vec<AreaDto>> {
148 let query = diesel::insert_into(hydrologies::table).values(&new_hydrologies);
149 debug!("{}", debug_query::<Pg, _>(&query));
150 let hydrologies = query
151 .get_results::<Hydrology>(conn)
152 .await?
153 .into_iter()
154 .map(Into::into)
155 .collect::<Vec<AreaDto>>();
156 Ok(hydrologies)
157}
158
159pub async fn create_soil_textures(
164 new_soil_textures: Vec<SoilTexture>,
165 conn: &mut AsyncPgConnection,
166) -> QueryResult<Vec<AreaDto>> {
167 let query = diesel::insert_into(soil_textures::table).values(&new_soil_textures);
168 debug!("{}", debug_query::<Pg, _>(&query));
169 let soil_textures = query
170 .get_results::<SoilTexture>(conn)
171 .await?
172 .into_iter()
173 .map(Into::into)
174 .collect::<Vec<AreaDto>>();
175 Ok(soil_textures)
176}
177
178pub async fn update_shadings(
183 updates: Vec<UpdateShading>,
184 conn: &mut AsyncPgConnection,
185) -> QueryResult<Vec<AreaDto>> {
186 conn.transaction(|transaction| {
187 Box::pin(async {
188 let mut results = Vec::with_capacity(updates.len());
189 for update in updates {
190 results.push(AreaDto::from(
191 diesel::update(shadings::table.find(update.id))
192 .set(update)
193 .get_result::<Shading>(transaction)
194 .await?,
195 ));
196 }
197 Ok(results) as QueryResult<Vec<AreaDto>>
198 })
199 })
200 .await
201}
202
203pub async fn update_hydrologies(
208 updates: Vec<UpdateHydrology>,
209 conn: &mut AsyncPgConnection,
210) -> QueryResult<Vec<AreaDto>> {
211 conn.transaction(|transaction| {
212 Box::pin(async {
213 let mut results = Vec::with_capacity(updates.len());
214 for update in updates {
215 results.push(AreaDto::from(
216 diesel::update(hydrologies::table.find(update.id))
217 .set(update)
218 .get_result::<Hydrology>(transaction)
219 .await?,
220 ));
221 }
222 Ok(results) as QueryResult<Vec<AreaDto>>
223 })
224 })
225 .await
226}
227
228pub async fn update_soil_textures(
233 updates: Vec<UpdateSoilTexture>,
234 conn: &mut AsyncPgConnection,
235) -> QueryResult<Vec<AreaDto>> {
236 conn.transaction(|transaction| {
237 Box::pin(async {
238 let mut results = Vec::with_capacity(updates.len());
239 for update in updates {
240 results.push(AreaDto::from(
241 diesel::update(soil_textures::table.find(update.id))
242 .set(update)
243 .get_result::<SoilTexture>(transaction)
244 .await?,
245 ));
246 }
247 Ok(results) as QueryResult<Vec<AreaDto>>
248 })
249 })
250 .await
251}
252
253pub async fn delete_areas_by_ids(
258 area_kind: AreaKind,
259 ids: Vec<Uuid>,
260 conn: &mut AsyncPgConnection,
261) -> QueryResult<usize> {
262 let result = match area_kind {
263 AreaKind::Shade => {
264 let query = diesel::delete(shadings::table.filter(shadings::id.eq_any(ids)));
265 debug!("{}", debug_query::<Pg, _>(&query));
266 query.execute(conn).await?
267 }
268 AreaKind::Hydrology => {
269 let query = diesel::delete(hydrologies::table.filter(hydrologies::id.eq_any(ids)));
270 debug!("{}", debug_query::<Pg, _>(&query));
271 query.execute(conn).await?
272 }
273 AreaKind::SoilTexture => {
274 let query = diesel::delete(soil_textures::table.filter(soil_textures::id.eq_any(ids)));
275 debug!("{}", debug_query::<Pg, _>(&query));
276 query.execute(conn).await?
277 }
278 };
279 Ok(result)
280}