From b0daa4ff18fde8c2479f3f7d9ff7c84269d240d6 Mon Sep 17 00:00:00 2001 From: filipriec Date: Sat, 8 Mar 2025 19:42:02 +0100 Subject: [PATCH] tree with a modern linkage --- .../handlers/get_profile_tree.rs | 49 ++++++++++++------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/server/src/table_definition/handlers/get_profile_tree.rs b/server/src/table_definition/handlers/get_profile_tree.rs index 73bfedf..3d879e7 100644 --- a/server/src/table_definition/handlers/get_profile_tree.rs +++ b/server/src/table_definition/handlers/get_profile_tree.rs @@ -1,4 +1,4 @@ -// server/src/table_definition/handlers/get_profile_tree.rs +// src/table_definition/handlers/get_profile_tree.rs use tonic::{Request, Response, Status}; use sqlx::PgPool; use common::proto::multieko2::{ @@ -22,15 +22,25 @@ pub async fn get_profile_tree( .map_err(|e| Status::internal(format!("Failed to fetch profiles: {}", e)))?; for profile in profile_records { - // Get all tables with their dependencies + // Get all tables with their dependencies from the links table let tables = sqlx::query!( r#" SELECT td.table_name, - ltd.table_name as "linked_table_name?" + COALESCE( + json_agg( + json_build_object( + 'linked_name', ltd.table_name, + 'required', tdl.is_required + ) + ) FILTER (WHERE ltd.id IS NOT NULL), + '[]' + ) as dependencies FROM table_definitions td - LEFT JOIN table_definitions ltd ON td.linked_table_id = ltd.id + LEFT JOIN table_definition_links tdl ON td.id = tdl.source_table_id + LEFT JOIN table_definitions ltd ON tdl.linked_table_id = ltd.id WHERE td.profile_id = $1 + GROUP BY td.table_name "#, profile.id ) @@ -38,22 +48,23 @@ pub async fn get_profile_tree( .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 + let proto_tables = tables.into_iter() + .map(|record| { + // Handle the Option properly + let dependencies = record.dependencies + .map(|val| serde_json::from_value::>(val)) + .transpose() + .unwrap_or_else(|_| Some(Vec::new())) + .unwrap_or_default(); + + Table { + name: record.table_name, + depends_on: dependencies + .into_iter() + .filter_map(|d| d["linked_name"].as_str().map(|s| s.to_string())) + .collect() + } }) .collect();