use rusqlite::Statement;
use termtree::Tree;
pub struct QueryPlanRenderer {
path: Vec<(u64, Tree<String>)>,
}
impl QueryPlanRenderer {
pub fn new() -> Self {
Self {
path: vec![(0_u64, Tree::new("QUERY PLAN".to_string()))],
}
}
pub fn render_tree(mut self, mut explain_stmt: Statement) -> rusqlite::Result<String> {
let mut rows = explain_stmt.raw_query();
while let Some(row) = rows.next()? {
let id: u64 = row.get(0)?;
let parent_id: u64 = row.get(1)?;
let label: String = row.get(3)?;
self.fold_up_to(parent_id);
self.path.push((id, label.into()));
}
self.fold_up_to(0);
let (_, root) = self.path.pop().expect("Always present");
Ok(root.to_string())
}
fn fold_up_to(&mut self, id: u64) {
while self.path.last().expect("Always present").0 > id {
let (_, top) = self.path.pop().expect("Always present");
self.path.last_mut().map(|(_, last)| last.push(top)).expect("Always present");
}
}
}