rorm_sql/
select_column.rs

1use std::fmt::Write;
2
3use crate::aggregation::SelectAggregator;
4
5/**
6Trait representing a column builder.
7*/
8pub trait SelectColumn {
9    /**
10    Build the column selector in the provided String.
11    */
12    fn build(&self, s: &mut String);
13}
14
15/**
16Representation of a select identifier.
17
18This is due to the presence of join expressions and some reserved keywords in postgres.
19 */
20#[derive(Debug, Clone, Copy)]
21pub struct SelectColumnData<'until_build> {
22    /// Optional name of the table
23    pub table_name: Option<&'until_build str>,
24    /// Name of the column
25    pub column_name: &'until_build str,
26    /// Optional alias to set for the column
27    pub select_alias: Option<&'until_build str>,
28    /// Optional aggregation function
29    pub aggregation: Option<SelectAggregator>,
30}
31
32/**
33Representation of the column selector and implementation of the [SelectColumn] trait.
34
35Should only be constructed via [DBImpl::select_column](crate::DBImpl::select_column).
36 */
37#[derive(Clone, Debug)]
38pub enum SelectColumnImpl<'until_build> {
39    /// SQLite representation of a column selector expression.
40    #[cfg(feature = "sqlite")]
41    SQLite(SelectColumnData<'until_build>),
42    /// MySQL representation of a column selector expression.
43    #[cfg(feature = "mysql")]
44    MySQL(SelectColumnData<'until_build>),
45    /// Postgres representation of a column selector expression.
46    #[cfg(feature = "postgres")]
47    Postgres(SelectColumnData<'until_build>),
48}
49
50impl SelectColumn for SelectColumnImpl<'_> {
51    fn build(&self, s: &mut String) {
52        match self {
53            #[cfg(feature = "sqlite")]
54            SelectColumnImpl::SQLite(d) => {
55                if let Some(aggregation) = d.aggregation {
56                    match aggregation {
57                        SelectAggregator::Avg => write!(s, "AVG("),
58                        SelectAggregator::Count => write!(s, "COUNT("),
59                        SelectAggregator::Sum => write!(s, "SUM("),
60                        SelectAggregator::Max => write!(s, "MAX("),
61                        SelectAggregator::Min => write!(s, "MIN("),
62                    }
63                    .unwrap();
64                }
65
66                if let Some(table_name) = d.table_name {
67                    write!(s, "\"{table_name}\".").unwrap();
68                }
69
70                write!(s, "\"{}\"", d.column_name).unwrap();
71
72                if d.aggregation.is_some() {
73                    write!(s, ")").unwrap();
74                }
75
76                if let Some(alias) = d.select_alias {
77                    write!(s, " AS {alias}").unwrap();
78                }
79            }
80            #[cfg(feature = "mysql")]
81            SelectColumnImpl::MySQL(d) => {
82                if let Some(aggregation) = d.aggregation {
83                    match aggregation {
84                        SelectAggregator::Avg => write!(s, "AVG("),
85                        SelectAggregator::Count => write!(s, "COUNT("),
86                        SelectAggregator::Sum => write!(s, "SUM("),
87                        SelectAggregator::Max => write!(s, "MAX("),
88                        SelectAggregator::Min => write!(s, "MIN("),
89                    }
90                    .unwrap();
91                }
92                if let Some(table_name) = d.table_name {
93                    write!(s, "`{table_name}`.").unwrap();
94                }
95
96                write!(s, "`{}`", d.column_name).unwrap();
97
98                if d.aggregation.is_some() {
99                    write!(s, ")").unwrap();
100                }
101
102                if let Some(alias) = d.select_alias {
103                    write!(s, " AS {alias}").unwrap();
104                }
105            }
106            #[cfg(feature = "postgres")]
107            SelectColumnImpl::Postgres(d) => {
108                if let Some(aggregation) = d.aggregation {
109                    match aggregation {
110                        SelectAggregator::Avg => write!(s, "AVG("),
111                        SelectAggregator::Count => write!(s, "COUNT("),
112                        SelectAggregator::Sum => write!(s, "SUM("),
113                        SelectAggregator::Max => write!(s, "MAX("),
114                        SelectAggregator::Min => write!(s, "MIN("),
115                    }
116                    .unwrap();
117                }
118                if let Some(table_name) = d.table_name {
119                    write!(s, "\"{table_name}\".").unwrap();
120                }
121
122                write!(s, "\"{}\"", d.column_name).unwrap();
123
124                if d.aggregation.is_some() {
125                    write!(s, ")").unwrap();
126                }
127
128                if let Some(alias) = d.select_alias {
129                    write!(s, " AS {alias}").unwrap();
130                }
131            }
132        }
133    }
134}