// server/src/table_definition/handlers/get_profile_tree.rs use tonic::{Request, Response, Status}; use sqlx::PgPool; use common::proto::multieko2::{ common::Empty, table_definition::{ ProfileTreeResponse, profile_tree_response::{Table, Profile} } }; pub async fn get_profile_tree( db_pool: &PgPool, _request: Request, ) -> Result, Status> { let mut profiles = Vec::new(); // Get all profiles let profile_records = sqlx::query!("SELECT id, name FROM profiles") .fetch_all(db_pool) .await .map_err(|e| Status::internal(format!("Failed to fetch profiles: {}", e)))?; for profile in profile_records { // Get all tables with their dependencies let tables = sqlx::query!( r#" SELECT td.table_name, ltd.table_name as "linked_table_name?" FROM table_definitions td LEFT JOIN table_definitions ltd ON td.linked_table_id = ltd.id WHERE td.profile_id = $1 "#, profile.id ) .fetch_all(db_pool) .await .map_err(|e| Status::internal(format!("Failed to fetch tables: {}", e)))?; // Group dependencies per table let mut table_map = std::collections::HashMap::new(); for table in tables { let entry = table_map.entry(table.table_name) .or_insert(Vec::new()); if let Some(linked) = table.linked_table_name { entry.push(linked); } } // Convert to protobuf format let proto_tables = table_map.into_iter() .map(|(name, depends_on)| Table { name, depends_on }) .collect(); profiles.push(Profile { name: profile.name, tables: proto_tables }); } Ok(Response::new(ProfileTreeResponse { profiles })) }