diff --git a/client-gui2 b/client-gui2 index 3993395d..052ee017 160000 --- a/client-gui2 +++ b/client-gui2 @@ -1 +1 @@ -Subproject commit 3993395df02afe72920c1b44a86bcefda373be2b +Subproject commit 052ee01763576378dd0c378849b2e4e121312b29 diff --git a/common/proto/table_definition.proto b/common/proto/table_definition.proto index cf331750..3444dbea 100644 --- a/common/proto/table_definition.proto +++ b/common/proto/table_definition.proto @@ -85,6 +85,10 @@ service TableDefinition { // Drops a table and its metadata, then deletes the profile if it becomes empty. rpc DeleteTable(DeleteTableRequest) returns (DeleteTableResponse); + + // Deletes an entire profile only when none of its user or backend-managed + // tables, audit stores, document stores, or accounting stores contain data. + rpc DeleteProfile(DeleteProfileRequest) returns (DeleteProfileResponse); } message CreateCustomExchangeRatesTableRequest { @@ -716,6 +720,16 @@ message DeleteTableResponse { string message = 2; } +message DeleteProfileRequest { + string profile_name = 1; +} + +message DeleteProfileResponse { + bool success = 1; + string message = 2; + int32 tables_deleted = 3; +} + // How a column type is spelled in ColumnDefinition.field_type. enum ColumnTypeSpelling { // The name is the whole spelling: "text", "money", "gtin_13". diff --git a/common/src/proto/descriptor.bin b/common/src/proto/descriptor.bin index d1f18856..1c04fca6 100644 Binary files a/common/src/proto/descriptor.bin and b/common/src/proto/descriptor.bin differ diff --git a/common/src/proto/komp_ac.table_definition.rs b/common/src/proto/komp_ac.table_definition.rs index a573ed90..7947782a 100644 --- a/common/src/proto/komp_ac.table_definition.rs +++ b/common/src/proto/komp_ac.table_definition.rs @@ -805,6 +805,22 @@ pub struct DeleteTableResponse { #[prost(string, tag = "2")] pub message: ::prost::alloc::string::String, } +#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct DeleteProfileRequest { + #[prost(string, tag = "1")] + pub profile_name: ::prost::alloc::string::String, +} +#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct DeleteProfileResponse { + #[prost(bool, tag = "1")] + pub success: bool, + #[prost(string, tag = "2")] + pub message: ::prost::alloc::string::String, + #[prost(int32, tag = "3")] + pub tables_deleted: i32, +} /// Response describing the whole column-type vocabulary. /// /// This is the authority a client builds its column-type picker from: every rule @@ -1764,6 +1780,37 @@ pub mod table_definition_client { ); self.inner.unary(req, path, codec).await } + /// Deletes an entire profile only when none of its user or backend-managed + /// tables, audit stores, document stores, or accounting stores contain data. + pub async fn delete_profile( + &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_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/komp_ac.table_definition.TableDefinition/DeleteProfile", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert( + GrpcMethod::new( + "komp_ac.table_definition.TableDefinition", + "DeleteProfile", + ), + ); + self.inner.unary(req, path, codec).await + } } } /// Generated server implementations. @@ -1951,6 +1998,15 @@ pub mod table_definition_server { tonic::Response, tonic::Status, >; + /// Deletes an entire profile only when none of its user or backend-managed + /// tables, audit stores, document stores, or accounting stores contain data. + async fn delete_profile( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; } /// The TableDefinition service manages the entire lifecycle of user-defined /// tables (stored as both metadata and physical PostgreSQL tables) inside @@ -2947,6 +3003,52 @@ pub mod table_definition_server { }; Box::pin(fut) } + "/komp_ac.table_definition.TableDefinition/DeleteProfile" => { + #[allow(non_camel_case_types)] + struct DeleteProfileSvc(pub Arc); + impl< + T: TableDefinition, + > tonic::server::UnaryService + for DeleteProfileSvc { + type Response = super::DeleteProfileResponse; + 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 { + ::delete_profile(&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 = DeleteProfileSvc(inner); + let codec = tonic_prost::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( diff --git a/komp-app/src/grpc.rs b/komp-app/src/grpc.rs index de04bd7c..66bf2747 100644 --- a/komp-app/src/grpc.rs +++ b/komp-app/src/grpc.rs @@ -1299,6 +1299,19 @@ impl GrpcClient { .into_inner()) } + pub async fn delete_profile( + &mut self, + request: common::proto::komp_ac::table_definition::DeleteProfileRequest, + ) -> Result { + let request = self.authenticated_request(request)?; + Ok(self + .table_definition_client + .delete_profile(request) + .await + .context("gRPC DeleteProfile call failed")? + .into_inner()) + } + pub async fn copy_profile( &mut self, request: common::proto::komp_ac::table_definition::CopyProfileRequest, diff --git a/server b/server index d3c676d6..a1ce6f6d 160000 --- a/server +++ b/server @@ -1 +1 @@ -Subproject commit d3c676d64a760acbc1e35bc05af800c014deb81d +Subproject commit a1ce6f6d6c227d3a4700338295909666f723955c