1use crate::{
2 DataSet, Driver, DynQuery, EitherIterator, Expression, ExpressionCollection, NA, SqlWriter,
3};
4use std::{iter, marker::PhantomData};
5
6pub struct SelectQueryBuilder<Select, From, Where, GroupBy, Having, OrderBy, Limit> {
7 pub(crate) select: Select,
8 pub(crate) from: Option<From>,
9 pub(crate) where_condition: Option<Where>,
10 pub(crate) group_by: Option<GroupBy>,
11 pub(crate) having: Option<Having>,
12 pub(crate) order_by: Option<OrderBy>,
13 pub(crate) limit: Option<u32>,
14 pub(crate) _l: PhantomData<Limit>,
15}
16
17impl<S> SelectQueryBuilder<S, NA, NA, NA, NA, NA, NA> {
18 pub fn from<From: DataSet>(
19 self,
20 from: From,
21 ) -> SelectQueryBuilder<S, From, NA, NA, NA, NA, NA> {
22 SelectQueryBuilder {
23 select: self.select,
24 from: Some(from),
25 where_condition: Default::default(),
26 group_by: Default::default(),
27 having: Default::default(),
28 order_by: Default::default(),
29 limit: Default::default(),
30 _l: Default::default(),
31 }
32 }
33}
34
35impl<S, F> SelectQueryBuilder<S, F, NA, NA, NA, NA, NA> {
36 pub fn where_condition<Where>(
37 self,
38 condition: Where,
39 ) -> SelectQueryBuilder<S, F, Where, NA, NA, NA, NA>
40 where
41 Where: Expression,
42 {
43 SelectQueryBuilder {
44 select: self.select,
45 from: self.from,
46 where_condition: Some(condition),
47 group_by: Default::default(),
48 having: Default::default(),
49 order_by: Default::default(),
50 limit: Default::default(),
51 _l: Default::default(),
52 }
53 }
54}
55
56impl<S, F, W> SelectQueryBuilder<S, F, W, NA, NA, NA, NA> {
57 pub fn group_by<GroupBy>(
58 self,
59 group_by: GroupBy,
60 ) -> SelectQueryBuilder<S, F, W, GroupBy, NA, NA, NA>
61 where
62 GroupBy: Clone,
63 {
64 SelectQueryBuilder {
65 select: self.select,
66 from: self.from,
67 where_condition: self.where_condition,
68 group_by: Some(group_by),
69 having: Default::default(),
70 order_by: Default::default(),
71 limit: Default::default(),
72 _l: Default::default(),
73 }
74 }
75}
76
77impl<S, F, W, G> SelectQueryBuilder<S, F, W, G, NA, NA, NA> {
78 pub fn having<Having: Expression>(
79 self,
80 having: Having,
81 ) -> SelectQueryBuilder<S, F, W, G, Having, NA, NA> {
82 SelectQueryBuilder {
83 select: self.select,
84 from: self.from,
85 where_condition: self.where_condition,
86 group_by: self.group_by,
87 having: Some(having),
88 order_by: Default::default(),
89 limit: Default::default(),
90 _l: Default::default(),
91 }
92 }
93}
94
95impl<S, F, W, G, H> SelectQueryBuilder<S, F, W, G, H, NA, NA> {
96 pub fn order_by<OrderBy>(
97 self,
98 order_by: OrderBy,
99 ) -> SelectQueryBuilder<S, F, W, G, H, OrderBy, NA> {
100 SelectQueryBuilder {
101 select: self.select,
102 from: self.from,
103 where_condition: self.where_condition,
104 group_by: self.group_by,
105 having: self.having,
106 order_by: Some(order_by),
107 limit: None,
108 _l: Default::default(),
109 }
110 }
111}
112
113impl<S, F, W, G, H, O> SelectQueryBuilder<S, F, W, G, H, O, NA> {
114 pub fn limit(self, limit: Option<u32>) -> SelectQueryBuilder<S, F, W, G, H, O, u32> {
115 SelectQueryBuilder {
116 select: self.select,
117 from: self.from,
118 where_condition: self.where_condition,
119 group_by: self.group_by,
120 having: self.having,
121 order_by: self.order_by,
122 limit,
123 _l: Default::default(),
124 }
125 }
126}
127
128impl<S, From, W, G, H, O, L> SelectQueryBuilder<S, From, W, G, H, O, L>
129where
130 S: ExpressionCollection,
131 From: DataSet,
132 W: Expression,
133 G: ExpressionCollection,
134 H: Expression,
135 O: ExpressionCollection,
136{
137 pub fn get_select(&self) -> impl Iterator<Item = impl Expression> + Clone {
138 self.select.expr_iter()
139 }
140
141 pub fn get_from(&self) -> &Option<From> {
142 &self.from
143 }
144
145 pub fn get_where_condition(&self) -> &Option<impl Expression> {
146 &self.where_condition
147 }
148
149 pub fn get_group_by(&self) -> impl Iterator<Item = impl Expression> + Clone {
150 match &self.group_by {
151 Some(v) => EitherIterator::Left(v.expr_iter()),
152 None => EitherIterator::Right(iter::empty()),
153 }
154 }
155
156 pub fn get_having(&self) -> &Option<impl Expression> {
157 &self.having
158 }
159
160 pub fn get_order_by(&self) -> impl Iterator<Item = impl Expression> + Clone {
161 match &self.order_by {
162 Some(v) => EitherIterator::Left(v.expr_iter()),
163 None => EitherIterator::Right(iter::empty()),
164 }
165 }
166
167 pub fn get_limit(&self) -> Option<u32> {
168 self.limit
169 }
170
171 pub fn build<D: Driver>(&self, driver: &D) -> String {
172 let writer = driver.sql_writer();
173 let mut query = DynQuery::default();
174 writer.write_select(&mut query, self);
175 query.into_buffer()
176 }
177
178 pub fn build_into<D: Driver>(&self, driver: &D, out: &mut DynQuery) {
179 let writer = driver.sql_writer();
180 writer.write_select(out, self);
181 }
182}
183
184pub trait SelectQuery<From>
185where
186 From: DataSet,
188{
189 fn get_select(&self) -> impl Iterator<Item = impl Expression> + Clone;
190 fn get_from<'s>(&'s self) -> &'s Option<From>;
191 fn get_where_condition<'s>(&'s self) -> &'s Option<impl Expression>;
192 fn get_group_by(&self) -> impl Iterator<Item = impl Expression> + Clone;
193 fn get_having(&self) -> &Option<impl Expression>;
194 fn get_order_by(&self) -> impl Iterator<Item = impl Expression> + Clone;
195 fn get_limit(&self) -> Option<u32>;
196 fn build<D: Driver>(&self, driver: &D) -> String;
197 fn build_into<D: Driver>(&self, driver: &D, out: &mut DynQuery);
198}
199
200impl<S, From, W, G, H, O, L> SelectQuery<From> for SelectQueryBuilder<S, From, W, G, H, O, L>
201where
202 S: ExpressionCollection,
203 From: DataSet,
204 W: Expression,
205 G: ExpressionCollection,
206 H: Expression,
207 O: ExpressionCollection,
208{
209 fn get_select(&self) -> impl Iterator<Item = impl Expression> + Clone {
210 self.get_select()
211 }
212
213 fn get_from(&self) -> &Option<From> {
214 self.get_from()
215 }
216
217 fn get_where_condition(&self) -> &Option<impl Expression> {
218 self.get_where_condition()
219 }
220
221 fn get_group_by(&self) -> impl Iterator<Item = impl Expression> + Clone {
222 self.get_group_by()
223 }
224
225 fn get_having(&self) -> &Option<impl Expression> {
226 self.get_having()
227 }
228
229 fn get_order_by(&self) -> impl Iterator<Item = impl Expression> + Clone {
230 self.get_order_by()
231 }
232
233 fn get_limit(&self) -> Option<u32> {
234 self.get_limit()
235 }
236
237 fn build<D: Driver>(&self, driver: &D) -> String {
238 self.build(driver)
239 }
240
241 fn build_into<D: Driver>(&self, driver: &D, out: &mut DynQuery) {
242 self.build_into(driver, out);
243 }
244}