use crate::errors::{Error, Result};
use crate::query::Filter;
use crate::Bins;
use crate::Value;
#[derive(Clone, Debug)]
pub struct Aggregation {
pub package_name: String,
pub function_name: String,
pub function_args: Option<Vec<Value>>,
}
#[derive(Clone, Debug)]
pub struct Statement {
pub namespace: String,
pub set_name: String,
pub bins: Bins,
pub filters: Option<Vec<Filter>>,
pub aggregation: Option<Aggregation>,
}
impl Statement {
pub fn new(namespace: &str, set_name: &str, bins: Bins) -> Self {
Statement {
namespace: namespace.to_owned(),
set_name: set_name.to_owned(),
bins,
aggregation: None,
filters: None,
}
}
pub fn add_filter(&mut self, filter: Filter) {
if let Some(ref mut filters) = self.filters {
filters.push(filter);
} else {
let filters = vec![filter];
self.filters = Some(filters);
}
}
pub fn set_aggregate_function(
&mut self,
package_name: &str,
function_name: &str,
function_args: Option<&[Value]>,
) {
let agg = Aggregation {
package_name: package_name.to_owned(),
function_name: function_name.to_owned(),
function_args: function_args.map(<[Value]>::to_vec),
};
self.aggregation = Some(agg);
}
pub(crate) fn validate(&self) -> Result<()> {
if let Some(ref filters) = self.filters {
if filters.len() > 1 {
return Err(Error::InvalidArgument(
"Too many filter expressions".to_string(),
));
}
}
if let Some(ref agg) = self.aggregation {
if agg.package_name.is_empty() {
return Err(Error::InvalidArgument("Empty UDF package name".to_string()));
}
if agg.function_name.is_empty() {
return Err(Error::InvalidArgument(
"Empty UDF function name".to_string(),
));
}
}
Ok(())
}
}