backend/model/entity/
plants_impl.rs1use diesel::{
4 debug_query, pg::Pg, BoolExpressionMethods, ExpressionMethods, JoinOnDsl,
5 NullableExpressionMethods, QueryDsl, QueryResult,
6};
7use diesel_async::{AsyncPgConnection, RunQueryDsl};
8use log::debug;
9
10use crate::{
11 db::{
12 function::{array_to_string, greatest3, similarity},
13 pagination::Paginate,
14 },
15 model::{
16 dto::{Page, PageParameters, PlantsSummaryDto},
17 entity::PlantsAndFamily,
18 },
19 schema::plants::{self, all_columns, common_name_de, common_name_en, unique_name},
20};
21diesel::alias!(crate::schema::plants as family_plants: FamilyPlants);
22
23use super::Plants;
24
25impl Plants {
26 pub async fn search(
34 search_query: &str,
35 page_parameters: PageParameters,
36 conn: &mut AsyncPgConnection,
37 ) -> QueryResult<Page<PlantsSummaryDto>> {
38 let p1 = family_plants;
39
40 let score = greatest3(
41 similarity(unique_name, search_query),
42 similarity(array_to_string(common_name_de, " "), search_query),
43 similarity(array_to_string(common_name_en, " "), search_query),
44 );
45 let query = plants::table
48 .left_join(p1.on(plants::family.eq(p1.field(plants::id).nullable())))
49 .select((
50 plants::all_columns,
51 p1.field(plants::unique_name).nullable(),
52 ))
53 .filter(
54 similarity(unique_name, search_query)
55 .gt(0.1)
56 .or(similarity(array_to_string(common_name_de, " "), search_query).gt(0.1))
57 .or(similarity(array_to_string(common_name_en, " "), search_query).gt(0.1)),
58 )
59 .order(score.desc())
60 .paginate(page_parameters.page)
61 .per_page(page_parameters.per_page);
62 debug!("{}", debug_query::<Pg, _>(&query));
63 query
64 .load_page::<PlantsAndFamily>(conn)
65 .await
66 .map(Page::from_entity)
67 }
68
69 pub async fn find_any(
74 page_parameters: PageParameters,
75 conn: &mut AsyncPgConnection,
76 ) -> QueryResult<Page<PlantsSummaryDto>> {
77 let p1 = family_plants;
78 let query = plants::table
79 .left_join(p1.on(plants::family.eq(p1.field(plants::id).nullable())))
80 .select((all_columns, p1.field(plants::unique_name).nullable()))
81 .into_boxed()
82 .paginate(page_parameters.page)
83 .per_page(page_parameters.per_page);
84 debug!("{}", debug_query::<Pg, _>(&query));
85 query
86 .load_page::<PlantsAndFamily>(conn)
87 .await
88 .map(Page::from_entity)
89 }
90
91 pub async fn find_by_id(
96 id: i64,
97 conn: &mut AsyncPgConnection,
98 ) -> QueryResult<PlantsSummaryDto> {
99 let p1 = family_plants;
100 let query = plants::table
101 .find(id)
102 .left_join(p1.on(plants::family.eq(p1.field(plants::id).nullable())))
103 .select((
104 plants::all_columns,
105 p1.field(plants::unique_name).nullable(),
106 ));
107 debug!("{}", debug_query::<Pg, _>(&query));
108 query.first::<PlantsAndFamily>(conn).await.map(Into::into)
109 }
110}