use crate::schema::Table;
use petgraph::graph::{DiGraph, NodeIndex};
use petgraph::algo::toposort;
use std::collections::HashMap;
use anyhow::Result;
pub fn sort_tables(tables: Vec<Table>) -> Result<Vec<Table>> {
let mut graph = DiGraph::<&Table, ()>::new();
let mut indices: HashMap<String, NodeIndex> = HashMap::new();
for table in &tables {
let idx = graph.add_node(table);
indices.insert(table.table_name.clone(), idx);
}
for table in &tables {
if let Some(child_idx) = indices.get(&table.table_name) {
for fk in &table.foreign_keys {
if let Some(parent_idx) = indices.get(&fk.ref_table) {
if child_idx != parent_idx {
graph.add_edge(*parent_idx, *child_idx, ());
}
}
}
}
}
match toposort(&graph, None) {
Ok(sorted_indices) => {
let sorted_tables: Vec<Table> = sorted_indices
.iter()
.map(|idx| {
let t = graph[*idx];
t.clone()
})
.collect();
Ok(sorted_tables)
}
Err(cycle) => {
let node = graph[cycle.node_id()];
println!("⚠️ Warning: Circular dependency detected involving table '{}'. Falling back to standard order.", node.table_name);
Ok(tables)
}
}
}