use std::fmt::Write;
use crate::aggregation::SelectAggregator;
pub trait SelectColumn {
fn build(&self, s: &mut String);
}
#[derive(Debug, Clone, Copy)]
pub struct SelectColumnData<'until_build> {
pub table_name: Option<&'until_build str>,
pub column_name: &'until_build str,
pub select_alias: Option<&'until_build str>,
pub aggregation: Option<SelectAggregator>,
}
#[derive(Clone, Debug)]
pub enum SelectColumnImpl<'until_build> {
#[cfg(feature = "sqlite")]
SQLite(SelectColumnData<'until_build>),
#[cfg(feature = "mysql")]
MySQL(SelectColumnData<'until_build>),
#[cfg(feature = "postgres")]
Postgres(SelectColumnData<'until_build>),
}
impl SelectColumn for SelectColumnImpl<'_> {
fn build(&self, s: &mut String) {
match self {
#[cfg(feature = "sqlite")]
SelectColumnImpl::SQLite(d) => {
if let Some(aggregation) = d.aggregation {
match aggregation {
SelectAggregator::Avg => write!(s, "AVG("),
SelectAggregator::Count => write!(s, "COUNT("),
SelectAggregator::Sum => write!(s, "SUM("),
SelectAggregator::Max => write!(s, "MAX("),
SelectAggregator::Min => write!(s, "MIN("),
}
.unwrap();
}
if let Some(table_name) = d.table_name {
write!(s, "\"{table_name}\".").unwrap();
}
write!(s, "\"{}\"", d.column_name).unwrap();
if d.aggregation.is_some() {
write!(s, ")").unwrap();
}
if let Some(alias) = d.select_alias {
write!(s, " AS {alias}").unwrap();
}
}
#[cfg(feature = "mysql")]
SelectColumnImpl::MySQL(d) => {
if let Some(aggregation) = d.aggregation {
match aggregation {
SelectAggregator::Avg => write!(s, "AVG("),
SelectAggregator::Count => write!(s, "COUNT("),
SelectAggregator::Sum => write!(s, "SUM("),
SelectAggregator::Max => write!(s, "MAX("),
SelectAggregator::Min => write!(s, "MIN("),
}
.unwrap();
}
if let Some(table_name) = d.table_name {
write!(s, "`{table_name}`.").unwrap();
}
write!(s, "`{}`", d.column_name).unwrap();
if d.aggregation.is_some() {
write!(s, ")").unwrap();
}
if let Some(alias) = d.select_alias {
write!(s, " AS {alias}").unwrap();
}
}
#[cfg(feature = "postgres")]
SelectColumnImpl::Postgres(d) => {
if let Some(aggregation) = d.aggregation {
match aggregation {
SelectAggregator::Avg => write!(s, "AVG("),
SelectAggregator::Count => write!(s, "COUNT("),
SelectAggregator::Sum => write!(s, "SUM("),
SelectAggregator::Max => write!(s, "MAX("),
SelectAggregator::Min => write!(s, "MIN("),
}
.unwrap();
}
if let Some(table_name) = d.table_name {
write!(s, "\"{table_name}\".").unwrap();
}
write!(s, "\"{}\"", d.column_name).unwrap();
if d.aggregation.is_some() {
write!(s, ")").unwrap();
}
if let Some(alias) = d.select_alias {
write!(s, " AS {alias}").unwrap();
}
}
}
}
}