typed_sql/query/select/
group.rs

1use 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> {}