use super::helpers::yield_alias;
use std::collections::HashMap;
use super::super::ast::YieldItem;
use super::super::result::ResultRow;
use crate::datatypes::values::Value;
use crate::graph::dir_graph::DirGraph;
const PROC: &str = "refresh_stats";
pub(super) fn execute_refresh_stats(
graph: &DirGraph,
_params: &HashMap<String, Value>,
yield_items: &[YieldItem],
) -> Result<Vec<ResultRow>, String> {
let src_var = yield_alias(yield_items, "src_type");
let edge_var = yield_alias(yield_items, "edge_type");
let tgt_var = yield_alias(yield_items, "tgt_type");
let count_var = yield_alias(yield_items, "count");
if src_var.is_none() && edge_var.is_none() && tgt_var.is_none() && count_var.is_none() {
return Err(format!(
"CALL {PROC}: must YIELD at least one of \
'src_type', 'edge_type', 'tgt_type', 'count'."
));
}
graph.invalidate_edge_type_counts_cache();
let mut triples = graph.get_or_compute_type_connectivity();
triples.sort_by(|a, b| {
a.src
.cmp(&b.src)
.then(a.conn.cmp(&b.conn))
.then(a.tgt.cmp(&b.tgt))
});
let mut rows = Vec::with_capacity(triples.len());
for t in triples {
let mut row = ResultRow::new();
if let Some(name) = &src_var {
row.projected.insert(name.clone(), Value::String(t.src));
}
if let Some(name) = &edge_var {
row.projected.insert(name.clone(), Value::String(t.conn));
}
if let Some(name) = &tgt_var {
row.projected.insert(name.clone(), Value::String(t.tgt));
}
if let Some(name) = &count_var {
row.projected
.insert(name.clone(), Value::Int64(t.count as i64));
}
rows.push(row);
}
Ok(rows)
}