use crate::{CollectError, Datatype, Dim, MetaDatatype, Partition, Table};
use std::collections::{HashMap, HashSet};
#[derive(Clone)]
pub struct Query {
pub datatypes: Vec<MetaDatatype>,
pub schemas: HashMap<Datatype, Table>,
pub time_dimension: TimeDimension,
pub partitions: Vec<Partition>,
pub partitioned_by: Vec<Dim>,
pub exclude_failed: bool,
pub js_tracer: Option<String>,
pub labels: QueryLabels,
}
#[derive(Clone)]
pub struct QueryLabels {
pub align: bool,
pub reorg_buffer: u64,
}
impl Query {
pub fn n_tasks(&self) -> usize {
self.datatypes.len() * self.partitions.len()
}
pub fn n_outputs(&self) -> usize {
self.datatypes.iter().map(|x| x.datatypes().len()).sum::<usize>() * self.partitions.len()
}
pub fn is_valid(&self) -> Result<(), CollectError> {
let mut all_datatypes = std::collections::HashSet::new();
for datatype in self.datatypes.iter() {
all_datatypes.extend(datatype.datatypes())
}
let mut requirements: HashSet<Dim> = HashSet::new();
for datatype in all_datatypes.iter() {
for dim in datatype.required_parameters() {
requirements.insert(dim);
}
}
for partition in self.partitions.iter() {
let partition_dims = partition.dims().into_iter().collect();
if !requirements.is_subset(&partition_dims) {
let missing: Vec<_> =
requirements.difference(&partition_dims).map(|x| x.to_string()).collect();
return Err(CollectError::CollectError(format!(
"need to specify {}",
missing.join(", ")
)))
}
}
Ok(())
}
}
#[derive(Clone)]
pub enum TimeDimension {
Blocks,
Transactions,
}