also get tree added, not working, breaks everything
This commit is contained in:
@@ -3,7 +3,7 @@ syntax = "proto3";
|
|||||||
package multieko2.adresar;
|
package multieko2.adresar;
|
||||||
|
|
||||||
import "common.proto";
|
import "common.proto";
|
||||||
import "table_structure.proto";
|
// import "table_structure.proto";
|
||||||
|
|
||||||
service Adresar {
|
service Adresar {
|
||||||
rpc PostAdresar (PostAdresarRequest) returns (AdresarResponse);
|
rpc PostAdresar (PostAdresarRequest) returns (AdresarResponse);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import "common.proto";
|
|||||||
|
|
||||||
service TableDefinition {
|
service TableDefinition {
|
||||||
rpc PostTableDefinition (PostTableDefinitionRequest) returns (TableDefinitionResponse);
|
rpc PostTableDefinition (PostTableDefinitionRequest) returns (TableDefinitionResponse);
|
||||||
|
rpc GetProfileTree (multieko2.common.Empty) returns (ProfileTreeResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
message PostTableDefinitionRequest {
|
message PostTableDefinitionRequest {
|
||||||
@@ -25,3 +26,17 @@ message TableDefinitionResponse {
|
|||||||
bool success = 1;
|
bool success = 1;
|
||||||
string sql = 2;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
Binary file not shown.
@@ -26,6 +26,28 @@ pub struct TableDefinitionResponse {
|
|||||||
#[prost(string, tag = "2")]
|
#[prost(string, tag = "2")]
|
||||||
pub sql: ::prost::alloc::string::String,
|
pub sql: ::prost::alloc::string::String,
|
||||||
}
|
}
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct ProfileTreeResponse {
|
||||||
|
#[prost(message, repeated, tag = "1")]
|
||||||
|
pub profiles: ::prost::alloc::vec::Vec<profile_tree_response::Profile>,
|
||||||
|
}
|
||||||
|
/// 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<Table>,
|
||||||
|
}
|
||||||
|
}
|
||||||
/// Generated client implementations.
|
/// Generated client implementations.
|
||||||
pub mod table_definition_client {
|
pub mod table_definition_client {
|
||||||
#![allow(
|
#![allow(
|
||||||
@@ -146,6 +168,35 @@ pub mod table_definition_client {
|
|||||||
);
|
);
|
||||||
self.inner.unary(req, path, codec).await
|
self.inner.unary(req, path, codec).await
|
||||||
}
|
}
|
||||||
|
pub async fn get_profile_tree(
|
||||||
|
&mut self,
|
||||||
|
request: impl tonic::IntoRequest<super::super::common::Empty>,
|
||||||
|
) -> std::result::Result<
|
||||||
|
tonic::Response<super::ProfileTreeResponse>,
|
||||||
|
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.
|
/// Generated server implementations.
|
||||||
@@ -168,6 +219,13 @@ pub mod table_definition_server {
|
|||||||
tonic::Response<super::TableDefinitionResponse>,
|
tonic::Response<super::TableDefinitionResponse>,
|
||||||
tonic::Status,
|
tonic::Status,
|
||||||
>;
|
>;
|
||||||
|
async fn get_profile_tree(
|
||||||
|
&self,
|
||||||
|
request: tonic::Request<super::super::common::Empty>,
|
||||||
|
) -> std::result::Result<
|
||||||
|
tonic::Response<super::ProfileTreeResponse>,
|
||||||
|
tonic::Status,
|
||||||
|
>;
|
||||||
}
|
}
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TableDefinitionServer<T> {
|
pub struct TableDefinitionServer<T> {
|
||||||
@@ -294,6 +352,52 @@ pub mod table_definition_server {
|
|||||||
};
|
};
|
||||||
Box::pin(fut)
|
Box::pin(fut)
|
||||||
}
|
}
|
||||||
|
"/multieko2.table_definition.TableDefinition/GetProfileTree" => {
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
struct GetProfileTreeSvc<T: TableDefinition>(pub Arc<T>);
|
||||||
|
impl<
|
||||||
|
T: TableDefinition,
|
||||||
|
> tonic::server::UnaryService<super::super::common::Empty>
|
||||||
|
for GetProfileTreeSvc<T> {
|
||||||
|
type Response = super::ProfileTreeResponse;
|
||||||
|
type Future = BoxFuture<
|
||||||
|
tonic::Response<Self::Response>,
|
||||||
|
tonic::Status,
|
||||||
|
>;
|
||||||
|
fn call(
|
||||||
|
&mut self,
|
||||||
|
request: tonic::Request<super::super::common::Empty>,
|
||||||
|
) -> Self::Future {
|
||||||
|
let inner = Arc::clone(&self.0);
|
||||||
|
let fut = async move {
|
||||||
|
<T as TableDefinition>::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 {
|
Box::pin(async move {
|
||||||
let mut response = http::Response::new(empty_body());
|
let mut response = http::Response::new(empty_body());
|
||||||
|
|||||||
@@ -4,8 +4,10 @@ use common::proto::multieko2::table_definition::{
|
|||||||
table_definition_server::TableDefinition,
|
table_definition_server::TableDefinition,
|
||||||
PostTableDefinitionRequest, TableDefinitionResponse
|
PostTableDefinitionRequest, TableDefinitionResponse
|
||||||
};
|
};
|
||||||
|
use common::proto::multieko2::table_definition::ProfileTreeResponse;
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
use crate::table_definition::handlers::post_table_definition;
|
use crate::table_definition::handlers::post_table_definition;
|
||||||
|
use crate::table_definition::handlers::get_profile_tree;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TableDefinitionService {
|
pub struct TableDefinitionService {
|
||||||
@@ -21,4 +23,10 @@ impl TableDefinition for TableDefinitionService {
|
|||||||
let response = post_table_definition(&self.db_pool, request.into_inner()).await?;
|
let response = post_table_definition(&self.db_pool, request.into_inner()).await?;
|
||||||
Ok(Response::new(response))
|
Ok(Response::new(response))
|
||||||
}
|
}
|
||||||
|
async fn get_profile_tree(
|
||||||
|
&self,
|
||||||
|
request: Request<()>,
|
||||||
|
) -> Result<Response<ProfileTreeResponse>, Status> {
|
||||||
|
get_profile_tree::get_profile_tree(&self.db_pool, request).await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
// src/table_definition/handlers.rs
|
// src/table_definition/handlers.rs
|
||||||
pub mod post_table_definition;
|
pub mod post_table_definition;
|
||||||
// pub mod get_table_definition;
|
pub mod get_profile_tree;
|
||||||
// pub mod list_table_definitions;
|
|
||||||
|
|
||||||
pub use post_table_definition::post_table_definition;
|
pub use post_table_definition::post_table_definition;
|
||||||
// pub use get_table_definition::get_table_definition;
|
pub use get_profile_tree::get_profile_tree;
|
||||||
// pub use list_table_definitions::list_table_definitions;
|
|
||||||
|
|||||||
61
server/src/table_definition/handlers/get_profile_tree.rs
Normal file
61
server/src/table_definition/handlers/get_profile_tree.rs
Normal file
@@ -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<Response<ProfileTreeResponse>, 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 }))
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user