use crate::ast::{AggregateFunc, Condition, Expr};
pub fn count() -> AggregateBuilder {
AggregateBuilder {
col: "*".to_string(),
func: AggregateFunc::Count,
distinct: false,
filter: None,
alias: None,
}
}
pub fn count_distinct(column: &str) -> AggregateBuilder {
AggregateBuilder {
col: column.to_string(),
func: AggregateFunc::Count,
distinct: true,
filter: None,
alias: None,
}
}
pub fn count_filter(conditions: Vec<Condition>) -> AggregateBuilder {
AggregateBuilder {
col: "*".to_string(),
func: AggregateFunc::Count,
distinct: false,
filter: Some(conditions),
alias: None,
}
}
pub fn sum(column: &str) -> AggregateBuilder {
AggregateBuilder {
col: column.to_string(),
func: AggregateFunc::Sum,
distinct: false,
filter: None,
alias: None,
}
}
pub fn avg(column: &str) -> AggregateBuilder {
AggregateBuilder {
col: column.to_string(),
func: AggregateFunc::Avg,
distinct: false,
filter: None,
alias: None,
}
}
pub fn min(column: &str) -> AggregateBuilder {
AggregateBuilder {
col: column.to_string(),
func: AggregateFunc::Min,
distinct: false,
filter: None,
alias: None,
}
}
pub fn max(column: &str) -> AggregateBuilder {
AggregateBuilder {
col: column.to_string(),
func: AggregateFunc::Max,
distinct: false,
filter: None,
alias: None,
}
}
pub fn array_agg(column: &str) -> AggregateBuilder {
AggregateBuilder {
col: column.to_string(),
func: AggregateFunc::ArrayAgg,
distinct: false,
filter: None,
alias: None,
}
}
pub fn json_agg(column: &str) -> AggregateBuilder {
AggregateBuilder {
col: column.to_string(),
func: AggregateFunc::JsonAgg,
distinct: false,
filter: None,
alias: None,
}
}
pub fn jsonb_agg(column: &str) -> AggregateBuilder {
AggregateBuilder {
col: column.to_string(),
func: AggregateFunc::JsonbAgg,
distinct: false,
filter: None,
alias: None,
}
}
pub fn bool_and(column: &str) -> AggregateBuilder {
AggregateBuilder {
col: column.to_string(),
func: AggregateFunc::BoolAnd,
distinct: false,
filter: None,
alias: None,
}
}
pub fn bool_or(column: &str) -> AggregateBuilder {
AggregateBuilder {
col: column.to_string(),
func: AggregateFunc::BoolOr,
distinct: false,
filter: None,
alias: None,
}
}
#[derive(Debug, Clone)]
pub struct AggregateBuilder {
pub(crate) col: String,
pub(crate) func: AggregateFunc,
pub(crate) distinct: bool,
pub(crate) filter: Option<Vec<Condition>>,
pub(crate) alias: Option<String>,
}
impl AggregateBuilder {
pub fn distinct(mut self) -> Self {
self.distinct = true;
self
}
pub fn filter(mut self, conditions: Vec<Condition>) -> Self {
self.filter = Some(conditions);
self
}
pub fn alias(mut self, name: &str) -> Expr {
self.alias = Some(name.to_string());
self.build()
}
pub fn build(self) -> Expr {
Expr::Aggregate {
col: self.col,
func: self.func,
distinct: self.distinct,
filter: self.filter,
alias: self.alias,
}
}
}
impl From<AggregateBuilder> for Expr {
fn from(builder: AggregateBuilder) -> Self {
builder.build()
}
}