From e53ed7bdc00793579bbcea79a314431516c643f9 Mon Sep 17 00:00:00 2001 From: filipriec Date: Sat, 1 Mar 2025 20:10:23 +0100 Subject: [PATCH] also get tree added, not working, breaks everything --- common/proto/adresar.proto | 2 +- common/proto/table_definition.proto | 15 +++ common/src/proto/descriptor.bin | Bin 12102 -> 12962 bytes .../src/proto/multieko2.table_definition.rs | 104 ++++++++++++++++++ .../services/table_definition_service.rs | 8 ++ server/src/table_definition/handlers.rs | 6 +- .../handlers/get_profile_tree.rs | 61 ++++++++++ 7 files changed, 191 insertions(+), 5 deletions(-) create mode 100644 server/src/table_definition/handlers/get_profile_tree.rs diff --git a/common/proto/adresar.proto b/common/proto/adresar.proto index 91db0af..33529c1 100644 --- a/common/proto/adresar.proto +++ b/common/proto/adresar.proto @@ -3,7 +3,7 @@ syntax = "proto3"; package multieko2.adresar; import "common.proto"; -import "table_structure.proto"; +// import "table_structure.proto"; service Adresar { rpc PostAdresar (PostAdresarRequest) returns (AdresarResponse); diff --git a/common/proto/table_definition.proto b/common/proto/table_definition.proto index d160eaf..a005be1 100644 --- a/common/proto/table_definition.proto +++ b/common/proto/table_definition.proto @@ -6,6 +6,7 @@ import "common.proto"; service TableDefinition { rpc PostTableDefinition (PostTableDefinitionRequest) returns (TableDefinitionResponse); + rpc GetProfileTree (multieko2.common.Empty) returns (ProfileTreeResponse); } message PostTableDefinitionRequest { @@ -25,3 +26,17 @@ message TableDefinitionResponse { bool success = 1; string sql = 2; } + +message ProfileTreeResponse { + message Table { + string name = 1; + repeated string depends_on = 2; + } + + message Profile { + string name = 1; + repeated Table tables = 2; + } + + repeated Profile profiles = 1; +} diff --git a/common/src/proto/descriptor.bin b/common/src/proto/descriptor.bin index a97f56581de14cdaacc3f32d347678e1dfb82d2c..8ce08e929edf8c0e8974f7c0a61bda994b611c0a 100644 GIT binary patch delta 1420 zcmZux%Wl&^6!nZJt}}L=*v`XAn#6gPq=X;}2mwN3gDUYRbcGNVrADe$k|<8MWXT$g zRIz2j8t8&QV1W=jB))(T;0w6d9^0Gla^{?S?wNZ%`Tp#q_t_`pP4FdiLFsh4x$V8n zwoaPLu|nV0f^Yhzb0bb=$=?zG*5SM%9o>2{XS_YS>Xf4Mk%u{>IM35MKU~aS9vpf*3(uQ){(Ls|J?k-7p$dXLc|{(59tfgY$iF?oIdo-PzQkV3wU^#mR$d?U1htQ&gMxxDv+q zL#4KL8QXSGYa4c$2=&&#;M3V-(|W>oJxs27`)`&j79-Ly*d9G1 z+2F(ImacK8NR(Kz%I*iR-TG?Gb)LZ^8P2ZW<(yL{Sxl2m0>5GQpw-k4he9S%*oMw( zSb`vfh{p(ox>kx2*y&DHlmV4vn}Q+?kshHHB?`b?BPLPW?8gXPa)Y68p_XhgS5OpO zjM#-zh+^dIm;)1|SdS5y7|oV20gz|wf|4^Ugz*(*sLN}Wm_%uuP8zR0%cLl#~k<- zEjtWFaE~Qc6%>K8Qc{KuN?L4*+bva`Fb1`lBh{lAbPO^_jfO)pMwLY?1OR?jriSi- zKv>NNH}iF32T$|$l_3bUu9;S7EnBQ14I^tDW<$j#Febw@W=+=4gf)PGYw9M?aRoW- z+k#;jd@X{|xuqH@26-!Qrx;qUTIEVo54@|MNqGFiT(yv5@N>;dic#-$QVf1>e?vrt zHFeoW92Mu-)osx#+*A*vuEMO*vU*9@XkEP|D`4>MB~inb_2D^1R|N=B`$<&5@EZDN zIpv{!ztTuC*!A5u*Y4n0ac~3HiKa>=@EV9G0Teh5a?u9>2z&;m=#>Eimx0^fQ|9>R GdGSB#{iN~$ delta 720 zcmX|;ze~eF6vyu_uO)qHntDmwBx)6*U_}Lgtd1^j{sRt*n^4j2-5do8=q|Vm9Tg{W z5ZwJ&bP&In+-1v$_ul8e@8$9Qv>4H|o!yFwii>j?fqcJx3lW&FmOTZQ8IUNru{vnxJsm(af|CM-E|W zuaB)oX)mNzTT-xuwM8LH7{;y!Nti4;f+QTSSP7s*OSa@;tW$4bZZ+!!16MSy`J$b} zb5XqlmE=|+SfcuIf+b4a1_Vij4a`}kCM|l^StYu(pO$iI&Kgr<-klK$zSyP$p)(Gm zG872DSjTn_rGzqDk{C, +} +/// Nested message and enum types in `ProfileTreeResponse`. +pub mod profile_tree_response { + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Table { + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, + #[prost(string, repeated, tag = "2")] + pub depends_on: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + } + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Profile { + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, + #[prost(message, repeated, tag = "2")] + pub tables: ::prost::alloc::vec::Vec, + } +} /// Generated client implementations. pub mod table_definition_client { #![allow( @@ -146,6 +168,35 @@ pub mod table_definition_client { ); self.inner.unary(req, path, codec).await } + pub async fn get_profile_tree( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/multieko2.table_definition.TableDefinition/GetProfileTree", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert( + GrpcMethod::new( + "multieko2.table_definition.TableDefinition", + "GetProfileTree", + ), + ); + self.inner.unary(req, path, codec).await + } } } /// Generated server implementations. @@ -168,6 +219,13 @@ pub mod table_definition_server { tonic::Response, tonic::Status, >; + async fn get_profile_tree( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; } #[derive(Debug)] pub struct TableDefinitionServer { @@ -294,6 +352,52 @@ pub mod table_definition_server { }; Box::pin(fut) } + "/multieko2.table_definition.TableDefinition/GetProfileTree" => { + #[allow(non_camel_case_types)] + struct GetProfileTreeSvc(pub Arc); + impl< + T: TableDefinition, + > tonic::server::UnaryService + for GetProfileTreeSvc { + type Response = super::ProfileTreeResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::get_profile_tree(&inner, request) + .await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = GetProfileTreeSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } _ => { Box::pin(async move { let mut response = http::Response::new(empty_body()); diff --git a/server/src/server/services/table_definition_service.rs b/server/src/server/services/table_definition_service.rs index 950e90d..d3b4227 100644 --- a/server/src/server/services/table_definition_service.rs +++ b/server/src/server/services/table_definition_service.rs @@ -4,8 +4,10 @@ use common::proto::multieko2::table_definition::{ table_definition_server::TableDefinition, PostTableDefinitionRequest, TableDefinitionResponse }; +use common::proto::multieko2::table_definition::ProfileTreeResponse; use sqlx::PgPool; use crate::table_definition::handlers::post_table_definition; +use crate::table_definition::handlers::get_profile_tree; #[derive(Debug)] pub struct TableDefinitionService { @@ -21,4 +23,10 @@ impl TableDefinition for TableDefinitionService { let response = post_table_definition(&self.db_pool, request.into_inner()).await?; Ok(Response::new(response)) } + async fn get_profile_tree( + &self, + request: Request<()>, + ) -> Result, Status> { + get_profile_tree::get_profile_tree(&self.db_pool, request).await + } } diff --git a/server/src/table_definition/handlers.rs b/server/src/table_definition/handlers.rs index 08b1087..2803921 100644 --- a/server/src/table_definition/handlers.rs +++ b/server/src/table_definition/handlers.rs @@ -1,8 +1,6 @@ // src/table_definition/handlers.rs pub mod post_table_definition; -// pub mod get_table_definition; -// pub mod list_table_definitions; +pub mod get_profile_tree; pub use post_table_definition::post_table_definition; -// pub use get_table_definition::get_table_definition; -// pub use list_table_definitions::list_table_definitions; +pub use get_profile_tree::get_profile_tree; diff --git a/server/src/table_definition/handlers/get_profile_tree.rs b/server/src/table_definition/handlers/get_profile_tree.rs new file mode 100644 index 0000000..1c875f4 --- /dev/null +++ b/server/src/table_definition/handlers/get_profile_tree.rs @@ -0,0 +1,61 @@ +// server/src/table_definition/handlers/get_profile_tree.rs +use tonic::{Request, Response, Status}; +use sqlx::PgPool; +use common::proto::multieko2::table_definition::ProfileTreeResponse; + +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)| ProfileTreeResponse::Table { + name, + depends_on + }) + .collect(); + + profiles.push(ProfileTreeResponse::Profile { + name: profile.name, + tables: proto_tables + }); + } + + Ok(Response::new(ProfileTreeResponse { profiles })) +}