use self::Aggregation::*;
use super::{Entity, query::QueryExt};
use zino_core::model::Query;
#[derive(Debug, Clone, Copy)]
#[non_exhaustive]
pub enum Aggregation<E: Entity> {
Count(E::Column, bool),
Sum(E::Column),
Avg(E::Column),
Min(E::Column),
Max(E::Column),
Stddev(E::Column),
Variance(E::Column),
JsonArrayagg(E::Column),
JsonObjectagg(E::Column, E::Column),
}
impl<E: Entity> Aggregation<E> {
pub(super) fn expr(&self) -> String {
match self {
Count(col, distinct) => {
let col_name = E::format_column(col);
let field = Query::format_field(&col_name);
if *distinct {
format!("count(distinct {field})")
} else {
format!("count({field})")
}
}
Sum(col) => {
let col_name = E::format_column(col);
let field = Query::format_field(&col_name);
format!("sum({field})")
}
Avg(col) => {
let col_name = E::format_column(col);
let field = Query::format_field(&col_name);
format!("avg({field})")
}
Min(col) => {
let col_name = E::format_column(col);
let field = Query::format_field(&col_name);
format!("min({field})")
}
Max(col) => {
let col_name = E::format_column(col);
let field = Query::format_field(&col_name);
format!("max({field})")
}
Stddev(col) => {
let col_name = E::format_column(col);
let field = Query::format_field(&col_name);
format!("stddev({field})")
}
Variance(col) => {
let col_name = E::format_column(col);
let field = Query::format_field(&col_name);
format!("variance({field})")
}
JsonArrayagg(col) => {
let col_name = E::format_column(col);
let field = Query::format_field(&col_name);
if cfg!(any(
feature = "orm-mariadb",
feature = "orm-mysql",
feature = "orm-tidb"
)) {
format!("json_arrayagg({field})")
} else if cfg!(feature = "orm-postgres") {
format!("jsonb_agg({field})")
} else {
format!("json_group_array({field})")
}
}
JsonObjectagg(key_col, val_col) => {
let key_col_name = E::format_column(key_col);
let val_col_name = E::format_column(val_col);
let key_field = Query::format_field(&key_col_name);
let val_field = Query::format_field(&val_col_name);
if cfg!(any(
feature = "orm-mariadb",
feature = "orm-mysql",
feature = "orm-tidb"
)) {
format!("json_objectagg({key_field}, {val_field})")
} else if cfg!(feature = "orm-postgres") {
format!("jsonb_object_agg({key_field}, {val_field})")
} else {
format!("json_group_object({key_field}, {val_field})")
}
}
}
}
}