1use std::marker::PhantomData;
9use std::sync::Arc;
10
11use crate::entity::IEntityType;
12use crate::error::EFResult;
13use crate::provider::{DbValue, DbValueConvertError, IDatabaseProvider};
14
15use super::state::QueryState;
16
17#[derive(Clone)]
19pub struct SelectQueryBuilder<T: IEntityType> {
20 pub(crate) state: QueryState,
21 pub(crate) provider: Option<Arc<dyn IDatabaseProvider>>,
22 pub(crate) _phantom: PhantomData<T>,
23}
24
25impl<T: IEntityType> SelectQueryBuilder<T> {
26 pub fn to_sql(&self) -> String {
28 if let Some(provider) = &self.provider {
29 let gen = provider.sql_generator();
30 self.state.to_sql_with(gen)
31 } else {
32 self.state.to_sql()
33 }
34 }
35
36 pub async fn to_list(self) -> EFResult<Vec<Vec<DbValue>>> {
38 let provider = self.provider.as_ref().ok_or_else(|| {
39 crate::error::EFError::configuration(
40 "No provider attached to SelectQueryBuilder.".to_string(),
41 )
42 })?;
43 let gen = provider.sql_generator();
44 let sql = self.state.to_sql_with(gen);
45 let params = self.state.all_params();
46 let mut conn = provider.get_connection().await?;
47 conn.query(&sql, ¶ms).await
48 }
49
50 async fn fetch_rows(self) -> EFResult<Vec<Vec<DbValue>>> {
59 self.to_list().await
60 }
61
62 pub async fn to_list_typed_1<V0>(self) -> EFResult<Vec<V0>>
64 where
65 V0: TryFrom<DbValue, Error = DbValueConvertError>,
66 {
67 let rows = self.fetch_rows().await?;
68 rows.into_iter()
69 .map(|row| {
70 let cell = row
71 .first()
72 .ok_or_else(|| crate::error::EFError::query("projection row has no columns"))?;
73 V0::try_from(cell.clone()).map_err(crate::error::EFError::from)
74 })
75 .collect()
76 }
77
78 pub async fn to_list_typed_2<V0, V1>(self) -> EFResult<Vec<(V0, V1)>>
80 where
81 V0: TryFrom<DbValue, Error = DbValueConvertError>,
82 V1: TryFrom<DbValue, Error = DbValueConvertError>,
83 {
84 let rows = self.fetch_rows().await?;
85 rows.into_iter()
86 .map(|row| {
87 let c0 = row.first().ok_or_else(|| {
88 crate::error::EFError::query("projection row missing column 0")
89 })?;
90 let c1 = row.get(1).ok_or_else(|| {
91 crate::error::EFError::query("projection row missing column 1")
92 })?;
93 Ok((
94 V0::try_from(c0.clone()).map_err(crate::error::EFError::from)?,
95 V1::try_from(c1.clone()).map_err(crate::error::EFError::from)?,
96 ))
97 })
98 .collect()
99 }
100
101 pub async fn to_list_typed_3<V0, V1, V2>(self) -> EFResult<Vec<(V0, V1, V2)>>
103 where
104 V0: TryFrom<DbValue, Error = DbValueConvertError>,
105 V1: TryFrom<DbValue, Error = DbValueConvertError>,
106 V2: TryFrom<DbValue, Error = DbValueConvertError>,
107 {
108 let rows = self.fetch_rows().await?;
109 rows.into_iter()
110 .map(|row| {
111 let c0 = row.first().ok_or_else(|| {
112 crate::error::EFError::query("projection row missing column 0")
113 })?;
114 let c1 = row.get(1).ok_or_else(|| {
115 crate::error::EFError::query("projection row missing column 1")
116 })?;
117 let c2 = row.get(2).ok_or_else(|| {
118 crate::error::EFError::query("projection row missing column 2")
119 })?;
120 Ok((
121 V0::try_from(c0.clone()).map_err(crate::error::EFError::from)?,
122 V1::try_from(c1.clone()).map_err(crate::error::EFError::from)?,
123 V2::try_from(c2.clone()).map_err(crate::error::EFError::from)?,
124 ))
125 })
126 .collect()
127 }
128
129 pub async fn to_list_typed_4<V0, V1, V2, V3>(self) -> EFResult<Vec<(V0, V1, V2, V3)>>
131 where
132 V0: TryFrom<DbValue, Error = DbValueConvertError>,
133 V1: TryFrom<DbValue, Error = DbValueConvertError>,
134 V2: TryFrom<DbValue, Error = DbValueConvertError>,
135 V3: TryFrom<DbValue, Error = DbValueConvertError>,
136 {
137 let rows = self.fetch_rows().await?;
138 rows.into_iter()
139 .map(|row| {
140 let c0 = row.first().ok_or_else(|| {
141 crate::error::EFError::query("projection row missing column 0")
142 })?;
143 let c1 = row.get(1).ok_or_else(|| {
144 crate::error::EFError::query("projection row missing column 1")
145 })?;
146 let c2 = row.get(2).ok_or_else(|| {
147 crate::error::EFError::query("projection row missing column 2")
148 })?;
149 let c3 = row.get(3).ok_or_else(|| {
150 crate::error::EFError::query("projection row missing column 3")
151 })?;
152 Ok((
153 V0::try_from(c0.clone()).map_err(crate::error::EFError::from)?,
154 V1::try_from(c1.clone()).map_err(crate::error::EFError::from)?,
155 V2::try_from(c2.clone()).map_err(crate::error::EFError::from)?,
156 V3::try_from(c3.clone()).map_err(crate::error::EFError::from)?,
157 ))
158 })
159 .collect()
160 }
161}