typed_sql/query/select/
group.rs1use super::Select;
2use crate::{
3 sql::CheckedSql,
4 types::field::{Field, Then},
5};
6use crate::{Table, ToSql};
7
8pub trait GroupOrder {
9 fn write_columns(&self, sql: &mut String);
10}
11
12impl<T, A> GroupOrder for Field<T, A>
13where
14 T: Table,
15{
16 fn write_columns(&self, sql: &mut String) {
17 self.write_field(sql);
18 }
19}
20
21impl<H, T> GroupOrder for Then<H, T>
22where
23 H: GroupOrder,
24 T: GroupOrder,
25{
26 fn write_columns(&self, sql: &mut String) {
27 self.head.write_columns(sql);
28 sql.push(',');
29 self.tail.write_columns(sql);
30 }
31}
32
33pub struct GroupBy<Q, O> {
34 stmt: Q,
35 order: O,
36}
37
38impl<Q, O> GroupBy<Q, O> {
39 pub(crate) fn new(stmt: Q, order: O) -> Self {
40 Self { stmt, order }
41 }
42}
43
44impl<S, O> Select for GroupBy<S, O>
45where
46 S: Select,
47 O: GroupOrder,
48{
49 type Selectable = S::Selectable;
50 type Queryable = S::Queryable;
51}
52
53impl<S, O> ToSql for GroupBy<S, O>
54where
55 S: Select,
56 O: GroupOrder,
57{
58 fn write_sql_unchecked(&self, sql: &mut String) {
59 self.stmt.write_sql_unchecked(sql);
60 sql.push_str(" GROUP BY ");
61 self.order.write_columns(sql);
62 }
63}
64
65impl<Q: CheckedSql, O> CheckedSql for GroupBy<Q, O> {}