Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b0133640f | ||
|
|
0600d3deaa | ||
|
|
90f8aedc3b |
11
Cargo.lock
generated
11
Cargo.lock
generated
@@ -493,7 +493,7 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "canvas"
|
name = "canvas"
|
||||||
version = "0.6.3"
|
version = "0.6.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -585,7 +585,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "client"
|
name = "client"
|
||||||
version = "0.6.3"
|
version = "0.6.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -641,7 +641,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "common"
|
name = "common"
|
||||||
version = "0.6.3"
|
version = "0.6.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"prost 0.13.5",
|
"prost 0.13.5",
|
||||||
"prost-build 0.14.1",
|
"prost-build 0.14.1",
|
||||||
@@ -3116,7 +3116,7 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "search"
|
name = "search"
|
||||||
version = "0.6.3"
|
version = "0.6.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"common",
|
"common",
|
||||||
@@ -3215,7 +3215,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "server"
|
name = "server"
|
||||||
version = "0.6.3"
|
version = "0.6.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bcrypt",
|
"bcrypt",
|
||||||
@@ -3252,6 +3252,7 @@ dependencies = [
|
|||||||
"tonic-reflection",
|
"tonic-reflection",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
|
"unicode-width 0.2.0",
|
||||||
"uuid",
|
"uuid",
|
||||||
"validator",
|
"validator",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ resolver = "2"
|
|||||||
[workspace.package]
|
[workspace.package]
|
||||||
# TODO: idk how to do the name, fix later
|
# TODO: idk how to do the name, fix later
|
||||||
# name = "komp_ac"
|
# name = "komp_ac"
|
||||||
version = "0.6.3"
|
version = "0.6.7"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "GPL-3.0-or-later"
|
license = "GPL-3.0-or-later"
|
||||||
authors = ["Filip Priečinský <filippriec@gmail.com>"]
|
authors = ["Filip Priečinský <filippriec@gmail.com>"]
|
||||||
|
|||||||
2
canvas
2
canvas
Submodule canvas updated: abbda5b7a9...d6e8ff58d5
2
client
2
client
Submodule client updated: ab990ac128...14a8b4ffbe
@@ -24,6 +24,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
".komp_ac.table_validation.PatternRule",
|
".komp_ac.table_validation.PatternRule",
|
||||||
"#[derive(serde::Serialize, serde::Deserialize)]",
|
"#[derive(serde::Serialize, serde::Deserialize)]",
|
||||||
)
|
)
|
||||||
|
.type_attribute(
|
||||||
|
".komp_ac.table_validation.PatternPosition",
|
||||||
|
"#[derive(serde::Serialize, serde::Deserialize)]",
|
||||||
|
)
|
||||||
|
.type_attribute(
|
||||||
|
".komp_ac.table_validation.CharacterConstraint",
|
||||||
|
"#[derive(serde::Serialize, serde::Deserialize)]",
|
||||||
|
)
|
||||||
.type_attribute(
|
.type_attribute(
|
||||||
".komp_ac.table_validation.PatternRules",
|
".komp_ac.table_validation.PatternRules",
|
||||||
"#[derive(serde::Serialize, serde::Deserialize)]",
|
"#[derive(serde::Serialize, serde::Deserialize)]",
|
||||||
@@ -32,6 +40,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
".komp_ac.table_validation.CustomFormatter",
|
".komp_ac.table_validation.CustomFormatter",
|
||||||
"#[derive(serde::Serialize, serde::Deserialize)]",
|
"#[derive(serde::Serialize, serde::Deserialize)]",
|
||||||
)
|
)
|
||||||
|
.type_attribute(
|
||||||
|
".komp_ac.table_validation.FormatterOption",
|
||||||
|
"#[derive(serde::Serialize, serde::Deserialize)]",
|
||||||
|
)
|
||||||
|
.type_attribute(
|
||||||
|
".komp_ac.table_validation.AllowedValues",
|
||||||
|
"#[derive(serde::Serialize, serde::Deserialize)]",
|
||||||
|
)
|
||||||
.type_attribute(
|
.type_attribute(
|
||||||
".komp_ac.table_validation.UpdateFieldValidationRequest",
|
".komp_ac.table_validation.UpdateFieldValidationRequest",
|
||||||
"#[derive(serde::Serialize, serde::Deserialize)]",
|
"#[derive(serde::Serialize, serde::Deserialize)]",
|
||||||
@@ -40,11 +56,27 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
".komp_ac.table_validation.UpdateFieldValidationResponse",
|
".komp_ac.table_validation.UpdateFieldValidationResponse",
|
||||||
"#[derive(serde::Serialize, serde::Deserialize)]",
|
"#[derive(serde::Serialize, serde::Deserialize)]",
|
||||||
)
|
)
|
||||||
|
.type_attribute(
|
||||||
|
".komp_ac.table_validation.ReplaceTableValidationRequest",
|
||||||
|
"#[derive(serde::Serialize, serde::Deserialize)]",
|
||||||
|
)
|
||||||
|
.type_attribute(
|
||||||
|
".komp_ac.table_validation.ReplaceTableValidationResponse",
|
||||||
|
"#[derive(serde::Serialize, serde::Deserialize)]",
|
||||||
|
)
|
||||||
// Enum -> readable strings in JSON ("BYTES", "DISPLAY_WIDTH")
|
// Enum -> readable strings in JSON ("BYTES", "DISPLAY_WIDTH")
|
||||||
.type_attribute(
|
.type_attribute(
|
||||||
".komp_ac.table_validation.CountMode",
|
".komp_ac.table_validation.CountMode",
|
||||||
"#[derive(serde::Serialize, serde::Deserialize)] #[serde(rename_all = \"SCREAMING_SNAKE_CASE\")]",
|
"#[derive(serde::Serialize, serde::Deserialize)] #[serde(rename_all = \"SCREAMING_SNAKE_CASE\")]",
|
||||||
)
|
)
|
||||||
|
.type_attribute(
|
||||||
|
".komp_ac.table_validation.PatternPositionKind",
|
||||||
|
"#[derive(serde::Serialize, serde::Deserialize)] #[serde(rename_all = \"SCREAMING_SNAKE_CASE\")]",
|
||||||
|
)
|
||||||
|
.type_attribute(
|
||||||
|
".komp_ac.table_validation.CharacterConstraintKind",
|
||||||
|
"#[derive(serde::Serialize, serde::Deserialize)] #[serde(rename_all = \"SCREAMING_SNAKE_CASE\")]",
|
||||||
|
)
|
||||||
.type_attribute(
|
.type_attribute(
|
||||||
".komp_ac.table_definition.ColumnDefinition",
|
".komp_ac.table_definition.ColumnDefinition",
|
||||||
"#[derive(serde::Serialize, serde::Deserialize)]",
|
"#[derive(serde::Serialize, serde::Deserialize)]",
|
||||||
@@ -61,6 +93,18 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
".komp_ac.table_definition.TableDefinitionResponse",
|
".komp_ac.table_definition.TableDefinitionResponse",
|
||||||
"#[derive(serde::Serialize, serde::Deserialize)]"
|
"#[derive(serde::Serialize, serde::Deserialize)]"
|
||||||
)
|
)
|
||||||
|
.type_attribute(
|
||||||
|
".komp_ac.table_definition.GetColumnAliasRenameHistoryRequest",
|
||||||
|
"#[derive(serde::Serialize, serde::Deserialize)]"
|
||||||
|
)
|
||||||
|
.type_attribute(
|
||||||
|
".komp_ac.table_definition.ColumnAliasRenameHistoryEntry",
|
||||||
|
"#[derive(serde::Serialize, serde::Deserialize)]"
|
||||||
|
)
|
||||||
|
.type_attribute(
|
||||||
|
".komp_ac.table_definition.GetColumnAliasRenameHistoryResponse",
|
||||||
|
"#[derive(serde::Serialize, serde::Deserialize)]"
|
||||||
|
)
|
||||||
.type_attribute(
|
.type_attribute(
|
||||||
".komp_ac.table_definition.RenameColumnAliasRequest",
|
".komp_ac.table_definition.RenameColumnAliasRequest",
|
||||||
"#[derive(serde::Serialize, serde::Deserialize)]"
|
"#[derive(serde::Serialize, serde::Deserialize)]"
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ service TableDefinition {
|
|||||||
// Pure data retrieval - no business logic.
|
// Pure data retrieval - no business logic.
|
||||||
rpc GetProfileDetails(GetProfileDetailsRequest) returns (GetProfileDetailsResponse);
|
rpc GetProfileDetails(GetProfileDetailsRequest) returns (GetProfileDetailsResponse);
|
||||||
|
|
||||||
|
// Returns the stored rename history for column aliases in one profile.
|
||||||
|
rpc GetColumnAliasRenameHistory(GetColumnAliasRenameHistoryRequest) returns (GetColumnAliasRenameHistoryResponse);
|
||||||
|
|
||||||
// Renames a user-visible column alias while keeping the physical column unchanged.
|
// Renames a user-visible column alias while keeping the physical column unchanged.
|
||||||
rpc RenameColumnAlias(RenameColumnAliasRequest) returns (RenameColumnAliasResponse);
|
rpc RenameColumnAlias(RenameColumnAliasRequest) returns (RenameColumnAliasResponse);
|
||||||
|
|
||||||
@@ -138,6 +141,31 @@ message GetProfileDetailsResponse {
|
|||||||
repeated TableDetail tables = 2;
|
repeated TableDetail tables = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Request to fetch recorded column alias rename history for one profile.
|
||||||
|
message GetColumnAliasRenameHistoryRequest {
|
||||||
|
string profile_name = 1;
|
||||||
|
|
||||||
|
// Optional filter. When omitted, returns all tables in the profile.
|
||||||
|
optional int64 table_definition_id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// One recorded column alias rename.
|
||||||
|
message ColumnAliasRenameHistoryEntry {
|
||||||
|
int64 id = 1;
|
||||||
|
string profile_name = 2;
|
||||||
|
int64 table_definition_id = 3;
|
||||||
|
string table_name = 4;
|
||||||
|
string old_column_name = 5;
|
||||||
|
string new_column_name = 6;
|
||||||
|
string created_at = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Response with stored column alias rename history rows.
|
||||||
|
message GetColumnAliasRenameHistoryResponse {
|
||||||
|
string profile_name = 1;
|
||||||
|
repeated ColumnAliasRenameHistoryEntry entries = 2;
|
||||||
|
}
|
||||||
|
|
||||||
// Describes a table with its columns and associated scripts.
|
// Describes a table with its columns and associated scripts.
|
||||||
message TableDetail {
|
message TableDetail {
|
||||||
string name = 1;
|
string name = 1;
|
||||||
|
|||||||
@@ -2,31 +2,55 @@
|
|||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
package komp_ac.table_validation;
|
package komp_ac.table_validation;
|
||||||
|
|
||||||
|
// This proto is the canonical server-side storage and distribution contract for
|
||||||
|
// client validation configuration.
|
||||||
|
//
|
||||||
|
// Design goals:
|
||||||
|
// - The server stores the entire field validation definition in one structured payload.
|
||||||
|
// - Clients fetch the validation rules for a table in one batch and map them to
|
||||||
|
// their local validation/runtime system (for example canvas).
|
||||||
|
// - Common validation must be represented as typed data, not as string mini-languages.
|
||||||
|
//
|
||||||
|
// Important split:
|
||||||
|
// - limits / pattern / allowed_values / required are validation rules.
|
||||||
|
// - mask / formatter are presentation and input-shaping metadata for clients.
|
||||||
|
|
||||||
// Request validation rules for a table
|
// Request validation rules for a table
|
||||||
message GetTableValidationRequest {
|
message GetTableValidationRequest {
|
||||||
string profileName = 1;
|
string profileName = 1;
|
||||||
string tableName = 2;
|
string tableName = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Response with field-level validations; if a field is omitted,
|
// Response with field-level validations for the whole table.
|
||||||
// no validation is applied (default unspecified).
|
// If a field is omitted, no validation configuration exists for that field.
|
||||||
message TableValidationResponse {
|
message TableValidationResponse {
|
||||||
repeated FieldValidation fields = 1;
|
repeated FieldValidation fields = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Field-level validation (extensible for future kinds)
|
// Field-level validation definition stored on the server and distributed to clients.
|
||||||
message FieldValidation {
|
message FieldValidation {
|
||||||
// MUST match your frontend FormState.dataKey for the column
|
// MUST match your frontend FormState.dataKey for the column
|
||||||
string dataKey = 1;
|
string dataKey = 1;
|
||||||
|
|
||||||
// Current: only CharacterLimits. More rules can be added later.
|
// Validation 1: length and counting rules.
|
||||||
CharacterLimits limits = 10;
|
CharacterLimits limits = 10;
|
||||||
// Future expansion:
|
|
||||||
PatternRules pattern = 11; // Validation 2
|
// Validation 2: position-based character constraints.
|
||||||
optional CustomFormatter formatter = 14; // Validation 4 – custom formatting logic
|
PatternRules pattern = 11;
|
||||||
|
|
||||||
|
// Exact-value whitelist.
|
||||||
|
AllowedValues allowed_values = 12;
|
||||||
|
|
||||||
|
// Client-side hint that this field participates in external/asynchronous validation UI.
|
||||||
|
bool external_validation_enabled = 13;
|
||||||
|
|
||||||
|
// Client-side formatter metadata. This is intentionally data-only, not executable code.
|
||||||
|
optional CustomFormatter formatter = 14;
|
||||||
|
|
||||||
|
// Client-side display mask metadata. The server stores raw data without mask literals.
|
||||||
DisplayMask mask = 3;
|
DisplayMask mask = 3;
|
||||||
// ExternalValidation external = 13;
|
|
||||||
// CustomFormatter formatter = 14;
|
// Field must be provided / treated as required by clients and server enforcement layers.
|
||||||
bool required = 4;
|
bool required = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +62,8 @@ enum CountMode {
|
|||||||
DISPLAY_WIDTH = 3;
|
DISPLAY_WIDTH = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Character limit validation (Validation 1)
|
// Character limit validation (Validation 1).
|
||||||
|
// These rules map directly to canvas CharacterLimits.
|
||||||
message CharacterLimits {
|
message CharacterLimits {
|
||||||
// When zero, the field is considered "not set". If both min/max are zero,
|
// When zero, the field is considered "not set". If both min/max are zero,
|
||||||
// the server should avoid sending this FieldValidation (no validation).
|
// the server should avoid sending this FieldValidation (no validation).
|
||||||
@@ -51,39 +76,91 @@ message CharacterLimits {
|
|||||||
CountMode countMode = 4; // defaults to CHARS if unspecified
|
CountMode countMode = 4; // defaults to CHARS if unspecified
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mask for pretty display
|
// Mask for pretty display only.
|
||||||
|
//
|
||||||
|
// This is not a validation rule by itself. It exists so clients can render and
|
||||||
|
// navigate masked input while still storing raw values server-side.
|
||||||
message DisplayMask {
|
message DisplayMask {
|
||||||
string pattern = 1; // e.g., "(###) ###-####" or "####-##-##"
|
string pattern = 1; // e.g., "(###) ###-####" or "####-##-##"
|
||||||
string input_char = 2; // e.g., "#"
|
string input_char = 2; // e.g., "#"
|
||||||
optional string template_char = 3; // e.g., "_"
|
optional string template_char = 3; // e.g., "_"
|
||||||
}
|
}
|
||||||
|
|
||||||
// One position‑based validation rule, similar to CharacterFilter + PositionRange
|
// Which positions a pattern rule applies to.
|
||||||
message PatternRule {
|
// This exists instead of a string syntax like "0-3" so the server can validate
|
||||||
// Range descriptor: how far the rule applies
|
// the structure directly and clients do not need to parse a DSL.
|
||||||
// Examples:
|
message PatternPosition {
|
||||||
// - "0" → Single position 0
|
PatternPositionKind kind = 1;
|
||||||
// - "0-3" → Range 0..3 inclusive
|
uint32 single = 2;
|
||||||
// - "from:5" → From position 5 onward
|
uint32 start = 3;
|
||||||
// - "0,2,5" → Multiple discrete positions
|
uint32 end = 4;
|
||||||
string range = 1;
|
repeated uint32 positions = 5;
|
||||||
|
|
||||||
// Character filter type, case‑insensitive keywords:
|
|
||||||
// "ALPHABETIC", "NUMERIC", "ALPHANUMERIC",
|
|
||||||
// "ONEOF(<chars>)", "EXACT(:)", "CUSTOM(<name>)"
|
|
||||||
string filter = 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum PatternPositionKind {
|
||||||
|
PATTERN_POSITION_KIND_UNSPECIFIED = 0;
|
||||||
|
PATTERN_POSITION_SINGLE = 1;
|
||||||
|
PATTERN_POSITION_RANGE = 2;
|
||||||
|
PATTERN_POSITION_FROM = 3;
|
||||||
|
PATTERN_POSITION_MULTIPLE = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// What type of character constraint a pattern rule applies.
|
||||||
|
// This mirrors the typed character filters used by canvas.
|
||||||
|
message CharacterConstraint {
|
||||||
|
CharacterConstraintKind kind = 1;
|
||||||
|
|
||||||
|
// Used when kind == CHARACTER_CONSTRAINT_EXACT.
|
||||||
|
optional string exact = 2;
|
||||||
|
|
||||||
|
// Used when kind == CHARACTER_CONSTRAINT_ONE_OF.
|
||||||
|
repeated string one_of = 3;
|
||||||
|
|
||||||
|
// Used when kind == CHARACTER_CONSTRAINT_REGEX.
|
||||||
|
optional string regex = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum CharacterConstraintKind {
|
||||||
|
CHARACTER_CONSTRAINT_KIND_UNSPECIFIED = 0;
|
||||||
|
CHARACTER_CONSTRAINT_ALPHABETIC = 1;
|
||||||
|
CHARACTER_CONSTRAINT_NUMERIC = 2;
|
||||||
|
CHARACTER_CONSTRAINT_ALPHANUMERIC = 3;
|
||||||
|
CHARACTER_CONSTRAINT_EXACT = 4;
|
||||||
|
CHARACTER_CONSTRAINT_ONE_OF = 5;
|
||||||
|
CHARACTER_CONSTRAINT_REGEX = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
// One position-based validation rule, similar to canvas PositionFilter.
|
||||||
|
message PatternRule {
|
||||||
|
PatternPosition position = 1;
|
||||||
|
CharacterConstraint constraint = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client-side formatter metadata.
|
||||||
|
// The formatter "type" is intended to be resolved by a client-side formatter registry.
|
||||||
message CustomFormatter {
|
message CustomFormatter {
|
||||||
// Formatter type identifier; handled client‑side.
|
// Formatter type identifier; handled client‑side.
|
||||||
// Examples: "PSCFormatter", "PhoneFormatter", "CreditCardFormatter", "DateFormatter"
|
// Examples: "PSCFormatter", "PhoneFormatter", "CreditCardFormatter", "DateFormatter"
|
||||||
string type = 1;
|
string type = 1;
|
||||||
|
|
||||||
// Optional free‑text note or parameters (e.g. locale, pattern)
|
repeated FormatterOption options = 2;
|
||||||
optional string description = 2;
|
optional string description = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collection of pattern rules for one field
|
message FormatterOption {
|
||||||
|
string key = 1;
|
||||||
|
string value = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exact-value whitelist configuration.
|
||||||
|
// This maps to canvas AllowedValues semantics.
|
||||||
|
message AllowedValues {
|
||||||
|
repeated string values = 1;
|
||||||
|
bool allow_empty = 2;
|
||||||
|
bool case_insensitive = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collection of pattern rules for one field.
|
||||||
message PatternRules {
|
message PatternRules {
|
||||||
// All rules that make up the validation logic
|
// All rules that make up the validation logic
|
||||||
repeated PatternRule rules = 1;
|
repeated PatternRule rules = 1;
|
||||||
@@ -92,11 +169,15 @@ message PatternRules {
|
|||||||
optional string description = 2;
|
optional string description = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Service to fetch validations for a table
|
// Service for storing and fetching field-validation definitions.
|
||||||
service TableValidationService {
|
service TableValidationService {
|
||||||
rpc GetTableValidation(GetTableValidationRequest) returns (TableValidationResponse);
|
rpc GetTableValidation(GetTableValidationRequest) returns (TableValidationResponse);
|
||||||
|
|
||||||
|
// Upsert a single field validation definition.
|
||||||
rpc UpdateFieldValidation(UpdateFieldValidationRequest) returns (UpdateFieldValidationResponse);
|
rpc UpdateFieldValidation(UpdateFieldValidationRequest) returns (UpdateFieldValidationResponse);
|
||||||
|
|
||||||
|
// Replace the full validation definition set for a table in one transaction.
|
||||||
|
rpc ReplaceTableValidation(ReplaceTableValidationRequest) returns (ReplaceTableValidationResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
message UpdateFieldValidationRequest {
|
message UpdateFieldValidationRequest {
|
||||||
@@ -110,3 +191,16 @@ message UpdateFieldValidationResponse {
|
|||||||
bool success = 1;
|
bool success = 1;
|
||||||
string message = 2;
|
string message = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message ReplaceTableValidationRequest {
|
||||||
|
string profileName = 1;
|
||||||
|
string tableName = 2;
|
||||||
|
|
||||||
|
// Full replacement set. Fields omitted here are removed from the stored config.
|
||||||
|
repeated FieldValidation fields = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ReplaceTableValidationResponse {
|
||||||
|
bool success = 1;
|
||||||
|
string message = 2;
|
||||||
|
}
|
||||||
|
|||||||
Binary file not shown.
@@ -125,6 +125,44 @@ pub struct GetProfileDetailsResponse {
|
|||||||
#[prost(message, repeated, tag = "2")]
|
#[prost(message, repeated, tag = "2")]
|
||||||
pub tables: ::prost::alloc::vec::Vec<TableDetail>,
|
pub tables: ::prost::alloc::vec::Vec<TableDetail>,
|
||||||
}
|
}
|
||||||
|
/// Request to fetch recorded column alias rename history for one profile.
|
||||||
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct GetColumnAliasRenameHistoryRequest {
|
||||||
|
#[prost(string, tag = "1")]
|
||||||
|
pub profile_name: ::prost::alloc::string::String,
|
||||||
|
/// Optional filter. When omitted, returns all tables in the profile.
|
||||||
|
#[prost(int64, optional, tag = "2")]
|
||||||
|
pub table_definition_id: ::core::option::Option<i64>,
|
||||||
|
}
|
||||||
|
/// One recorded column alias rename.
|
||||||
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct ColumnAliasRenameHistoryEntry {
|
||||||
|
#[prost(int64, tag = "1")]
|
||||||
|
pub id: i64,
|
||||||
|
#[prost(string, tag = "2")]
|
||||||
|
pub profile_name: ::prost::alloc::string::String,
|
||||||
|
#[prost(int64, tag = "3")]
|
||||||
|
pub table_definition_id: i64,
|
||||||
|
#[prost(string, tag = "4")]
|
||||||
|
pub table_name: ::prost::alloc::string::String,
|
||||||
|
#[prost(string, tag = "5")]
|
||||||
|
pub old_column_name: ::prost::alloc::string::String,
|
||||||
|
#[prost(string, tag = "6")]
|
||||||
|
pub new_column_name: ::prost::alloc::string::String,
|
||||||
|
#[prost(string, tag = "7")]
|
||||||
|
pub created_at: ::prost::alloc::string::String,
|
||||||
|
}
|
||||||
|
/// Response with stored column alias rename history rows.
|
||||||
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct GetColumnAliasRenameHistoryResponse {
|
||||||
|
#[prost(string, tag = "1")]
|
||||||
|
pub profile_name: ::prost::alloc::string::String,
|
||||||
|
#[prost(message, repeated, tag = "2")]
|
||||||
|
pub entries: ::prost::alloc::vec::Vec<ColumnAliasRenameHistoryEntry>,
|
||||||
|
}
|
||||||
/// Describes a table with its columns and associated scripts.
|
/// Describes a table with its columns and associated scripts.
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct TableDetail {
|
pub struct TableDetail {
|
||||||
@@ -383,6 +421,36 @@ pub mod table_definition_client {
|
|||||||
);
|
);
|
||||||
self.inner.unary(req, path, codec).await
|
self.inner.unary(req, path, codec).await
|
||||||
}
|
}
|
||||||
|
/// Returns the stored rename history for column aliases in one profile.
|
||||||
|
pub async fn get_column_alias_rename_history(
|
||||||
|
&mut self,
|
||||||
|
request: impl tonic::IntoRequest<super::GetColumnAliasRenameHistoryRequest>,
|
||||||
|
) -> std::result::Result<
|
||||||
|
tonic::Response<super::GetColumnAliasRenameHistoryResponse>,
|
||||||
|
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(
|
||||||
|
"/komp_ac.table_definition.TableDefinition/GetColumnAliasRenameHistory",
|
||||||
|
);
|
||||||
|
let mut req = request.into_request();
|
||||||
|
req.extensions_mut()
|
||||||
|
.insert(
|
||||||
|
GrpcMethod::new(
|
||||||
|
"komp_ac.table_definition.TableDefinition",
|
||||||
|
"GetColumnAliasRenameHistory",
|
||||||
|
),
|
||||||
|
);
|
||||||
|
self.inner.unary(req, path, codec).await
|
||||||
|
}
|
||||||
/// Renames a user-visible column alias while keeping the physical column unchanged.
|
/// Renames a user-visible column alias while keeping the physical column unchanged.
|
||||||
pub async fn rename_column_alias(
|
pub async fn rename_column_alias(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -486,6 +554,14 @@ pub mod table_definition_server {
|
|||||||
tonic::Response<super::GetProfileDetailsResponse>,
|
tonic::Response<super::GetProfileDetailsResponse>,
|
||||||
tonic::Status,
|
tonic::Status,
|
||||||
>;
|
>;
|
||||||
|
/// Returns the stored rename history for column aliases in one profile.
|
||||||
|
async fn get_column_alias_rename_history(
|
||||||
|
&self,
|
||||||
|
request: tonic::Request<super::GetColumnAliasRenameHistoryRequest>,
|
||||||
|
) -> std::result::Result<
|
||||||
|
tonic::Response<super::GetColumnAliasRenameHistoryResponse>,
|
||||||
|
tonic::Status,
|
||||||
|
>;
|
||||||
/// Renames a user-visible column alias while keeping the physical column unchanged.
|
/// Renames a user-visible column alias while keeping the physical column unchanged.
|
||||||
async fn rename_column_alias(
|
async fn rename_column_alias(
|
||||||
&self,
|
&self,
|
||||||
@@ -724,6 +800,60 @@ pub mod table_definition_server {
|
|||||||
};
|
};
|
||||||
Box::pin(fut)
|
Box::pin(fut)
|
||||||
}
|
}
|
||||||
|
"/komp_ac.table_definition.TableDefinition/GetColumnAliasRenameHistory" => {
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
struct GetColumnAliasRenameHistorySvc<T: TableDefinition>(
|
||||||
|
pub Arc<T>,
|
||||||
|
);
|
||||||
|
impl<
|
||||||
|
T: TableDefinition,
|
||||||
|
> tonic::server::UnaryService<
|
||||||
|
super::GetColumnAliasRenameHistoryRequest,
|
||||||
|
> for GetColumnAliasRenameHistorySvc<T> {
|
||||||
|
type Response = super::GetColumnAliasRenameHistoryResponse;
|
||||||
|
type Future = BoxFuture<
|
||||||
|
tonic::Response<Self::Response>,
|
||||||
|
tonic::Status,
|
||||||
|
>;
|
||||||
|
fn call(
|
||||||
|
&mut self,
|
||||||
|
request: tonic::Request<
|
||||||
|
super::GetColumnAliasRenameHistoryRequest,
|
||||||
|
>,
|
||||||
|
) -> Self::Future {
|
||||||
|
let inner = Arc::clone(&self.0);
|
||||||
|
let fut = async move {
|
||||||
|
<T as TableDefinition>::get_column_alias_rename_history(
|
||||||
|
&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 = GetColumnAliasRenameHistorySvc(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)
|
||||||
|
}
|
||||||
"/komp_ac.table_definition.TableDefinition/RenameColumnAlias" => {
|
"/komp_ac.table_definition.TableDefinition/RenameColumnAlias" => {
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
struct RenameColumnAliasSvc<T: TableDefinition>(pub Arc<T>);
|
struct RenameColumnAliasSvc<T: TableDefinition>(pub Arc<T>);
|
||||||
|
|||||||
@@ -7,40 +7,45 @@ pub struct GetTableValidationRequest {
|
|||||||
#[prost(string, tag = "2")]
|
#[prost(string, tag = "2")]
|
||||||
pub table_name: ::prost::alloc::string::String,
|
pub table_name: ::prost::alloc::string::String,
|
||||||
}
|
}
|
||||||
/// Response with field-level validations; if a field is omitted,
|
/// Response with field-level validations for the whole table.
|
||||||
/// no validation is applied (default unspecified).
|
/// If a field is omitted, no validation configuration exists for that field.
|
||||||
#[derive(serde::Serialize, serde::Deserialize)]
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct TableValidationResponse {
|
pub struct TableValidationResponse {
|
||||||
#[prost(message, repeated, tag = "1")]
|
#[prost(message, repeated, tag = "1")]
|
||||||
pub fields: ::prost::alloc::vec::Vec<FieldValidation>,
|
pub fields: ::prost::alloc::vec::Vec<FieldValidation>,
|
||||||
}
|
}
|
||||||
/// Field-level validation (extensible for future kinds)
|
/// Field-level validation definition stored on the server and distributed to clients.
|
||||||
#[derive(serde::Serialize, serde::Deserialize)]
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct FieldValidation {
|
pub struct FieldValidation {
|
||||||
/// MUST match your frontend FormState.dataKey for the column
|
/// MUST match your frontend FormState.dataKey for the column
|
||||||
#[prost(string, tag = "1")]
|
#[prost(string, tag = "1")]
|
||||||
pub data_key: ::prost::alloc::string::String,
|
pub data_key: ::prost::alloc::string::String,
|
||||||
/// Current: only CharacterLimits. More rules can be added later.
|
/// Validation 1: length and counting rules.
|
||||||
#[prost(message, optional, tag = "10")]
|
#[prost(message, optional, tag = "10")]
|
||||||
pub limits: ::core::option::Option<CharacterLimits>,
|
pub limits: ::core::option::Option<CharacterLimits>,
|
||||||
/// Future expansion:
|
/// Validation 2: position-based character constraints.
|
||||||
///
|
|
||||||
/// Validation 2
|
|
||||||
#[prost(message, optional, tag = "11")]
|
#[prost(message, optional, tag = "11")]
|
||||||
pub pattern: ::core::option::Option<PatternRules>,
|
pub pattern: ::core::option::Option<PatternRules>,
|
||||||
/// Validation 4 – custom formatting logic
|
/// Exact-value whitelist.
|
||||||
|
#[prost(message, optional, tag = "12")]
|
||||||
|
pub allowed_values: ::core::option::Option<AllowedValues>,
|
||||||
|
/// Client-side hint that this field participates in external/asynchronous validation UI.
|
||||||
|
#[prost(bool, tag = "13")]
|
||||||
|
pub external_validation_enabled: bool,
|
||||||
|
/// Client-side formatter metadata. This is intentionally data-only, not executable code.
|
||||||
#[prost(message, optional, tag = "14")]
|
#[prost(message, optional, tag = "14")]
|
||||||
pub formatter: ::core::option::Option<CustomFormatter>,
|
pub formatter: ::core::option::Option<CustomFormatter>,
|
||||||
|
/// Client-side display mask metadata. The server stores raw data without mask literals.
|
||||||
#[prost(message, optional, tag = "3")]
|
#[prost(message, optional, tag = "3")]
|
||||||
pub mask: ::core::option::Option<DisplayMask>,
|
pub mask: ::core::option::Option<DisplayMask>,
|
||||||
/// ExternalValidation external = 13;
|
/// Field must be provided / treated as required by clients and server enforcement layers.
|
||||||
/// CustomFormatter formatter = 14;
|
|
||||||
#[prost(bool, tag = "4")]
|
#[prost(bool, tag = "4")]
|
||||||
pub required: bool,
|
pub required: bool,
|
||||||
}
|
}
|
||||||
/// Character limit validation (Validation 1)
|
/// Character limit validation (Validation 1).
|
||||||
|
/// These rules map directly to canvas CharacterLimits.
|
||||||
#[derive(serde::Serialize, serde::Deserialize)]
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
|
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
|
||||||
pub struct CharacterLimits {
|
pub struct CharacterLimits {
|
||||||
@@ -57,7 +62,10 @@ pub struct CharacterLimits {
|
|||||||
#[prost(enumeration = "CountMode", tag = "4")]
|
#[prost(enumeration = "CountMode", tag = "4")]
|
||||||
pub count_mode: i32,
|
pub count_mode: i32,
|
||||||
}
|
}
|
||||||
/// Mask for pretty display
|
/// Mask for pretty display only.
|
||||||
|
///
|
||||||
|
/// This is not a validation rule by itself. It exists so clients can render and
|
||||||
|
/// navigate masked input while still storing raw values server-side.
|
||||||
#[derive(serde::Serialize, serde::Deserialize)]
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct DisplayMask {
|
pub struct DisplayMask {
|
||||||
@@ -71,24 +79,51 @@ pub struct DisplayMask {
|
|||||||
#[prost(string, optional, tag = "3")]
|
#[prost(string, optional, tag = "3")]
|
||||||
pub template_char: ::core::option::Option<::prost::alloc::string::String>,
|
pub template_char: ::core::option::Option<::prost::alloc::string::String>,
|
||||||
}
|
}
|
||||||
/// One position‑based validation rule, similar to CharacterFilter + PositionRange
|
/// Which positions a pattern rule applies to.
|
||||||
|
/// This exists instead of a string syntax like "0-3" so the server can validate
|
||||||
|
/// the structure directly and clients do not need to parse a DSL.
|
||||||
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct PatternPosition {
|
||||||
|
#[prost(enumeration = "PatternPositionKind", tag = "1")]
|
||||||
|
pub kind: i32,
|
||||||
|
#[prost(uint32, tag = "2")]
|
||||||
|
pub single: u32,
|
||||||
|
#[prost(uint32, tag = "3")]
|
||||||
|
pub start: u32,
|
||||||
|
#[prost(uint32, tag = "4")]
|
||||||
|
pub end: u32,
|
||||||
|
#[prost(uint32, repeated, tag = "5")]
|
||||||
|
pub positions: ::prost::alloc::vec::Vec<u32>,
|
||||||
|
}
|
||||||
|
/// What type of character constraint a pattern rule applies.
|
||||||
|
/// This mirrors the typed character filters used by canvas.
|
||||||
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct CharacterConstraint {
|
||||||
|
#[prost(enumeration = "CharacterConstraintKind", tag = "1")]
|
||||||
|
pub kind: i32,
|
||||||
|
/// Used when kind == CHARACTER_CONSTRAINT_EXACT.
|
||||||
|
#[prost(string, optional, tag = "2")]
|
||||||
|
pub exact: ::core::option::Option<::prost::alloc::string::String>,
|
||||||
|
/// Used when kind == CHARACTER_CONSTRAINT_ONE_OF.
|
||||||
|
#[prost(string, repeated, tag = "3")]
|
||||||
|
pub one_of: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
|
||||||
|
/// Used when kind == CHARACTER_CONSTRAINT_REGEX.
|
||||||
|
#[prost(string, optional, tag = "4")]
|
||||||
|
pub regex: ::core::option::Option<::prost::alloc::string::String>,
|
||||||
|
}
|
||||||
|
/// One position-based validation rule, similar to canvas PositionFilter.
|
||||||
#[derive(serde::Serialize, serde::Deserialize)]
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct PatternRule {
|
pub struct PatternRule {
|
||||||
/// Range descriptor: how far the rule applies
|
#[prost(message, optional, tag = "1")]
|
||||||
/// Examples:
|
pub position: ::core::option::Option<PatternPosition>,
|
||||||
/// - "0" → Single position 0
|
#[prost(message, optional, tag = "2")]
|
||||||
/// - "0-3" → Range 0..3 inclusive
|
pub constraint: ::core::option::Option<CharacterConstraint>,
|
||||||
/// - "from:5" → From position 5 onward
|
|
||||||
/// - "0,2,5" → Multiple discrete positions
|
|
||||||
#[prost(string, tag = "1")]
|
|
||||||
pub range: ::prost::alloc::string::String,
|
|
||||||
/// Character filter type, case‑insensitive keywords:
|
|
||||||
/// "ALPHABETIC", "NUMERIC", "ALPHANUMERIC",
|
|
||||||
/// "ONEOF(<chars>)", "EXACT(:)", "CUSTOM(<name>)"
|
|
||||||
#[prost(string, tag = "2")]
|
|
||||||
pub filter: ::prost::alloc::string::String,
|
|
||||||
}
|
}
|
||||||
|
/// Client-side formatter metadata.
|
||||||
|
/// The formatter "type" is intended to be resolved by a client-side formatter registry.
|
||||||
#[derive(serde::Serialize, serde::Deserialize)]
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct CustomFormatter {
|
pub struct CustomFormatter {
|
||||||
@@ -96,11 +131,32 @@ pub struct CustomFormatter {
|
|||||||
/// Examples: "PSCFormatter", "PhoneFormatter", "CreditCardFormatter", "DateFormatter"
|
/// Examples: "PSCFormatter", "PhoneFormatter", "CreditCardFormatter", "DateFormatter"
|
||||||
#[prost(string, tag = "1")]
|
#[prost(string, tag = "1")]
|
||||||
pub r#type: ::prost::alloc::string::String,
|
pub r#type: ::prost::alloc::string::String,
|
||||||
/// Optional free‑text note or parameters (e.g. locale, pattern)
|
#[prost(message, repeated, tag = "2")]
|
||||||
#[prost(string, optional, tag = "2")]
|
pub options: ::prost::alloc::vec::Vec<FormatterOption>,
|
||||||
|
#[prost(string, optional, tag = "3")]
|
||||||
pub description: ::core::option::Option<::prost::alloc::string::String>,
|
pub description: ::core::option::Option<::prost::alloc::string::String>,
|
||||||
}
|
}
|
||||||
/// Collection of pattern rules for one field
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct FormatterOption {
|
||||||
|
#[prost(string, tag = "1")]
|
||||||
|
pub key: ::prost::alloc::string::String,
|
||||||
|
#[prost(string, tag = "2")]
|
||||||
|
pub value: ::prost::alloc::string::String,
|
||||||
|
}
|
||||||
|
/// Exact-value whitelist configuration.
|
||||||
|
/// This maps to canvas AllowedValues semantics.
|
||||||
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct AllowedValues {
|
||||||
|
#[prost(string, repeated, tag = "1")]
|
||||||
|
pub values: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
|
||||||
|
#[prost(bool, tag = "2")]
|
||||||
|
pub allow_empty: bool,
|
||||||
|
#[prost(bool, tag = "3")]
|
||||||
|
pub case_insensitive: bool,
|
||||||
|
}
|
||||||
|
/// Collection of pattern rules for one field.
|
||||||
#[derive(serde::Serialize, serde::Deserialize)]
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct PatternRules {
|
pub struct PatternRules {
|
||||||
@@ -131,6 +187,25 @@ pub struct UpdateFieldValidationResponse {
|
|||||||
#[prost(string, tag = "2")]
|
#[prost(string, tag = "2")]
|
||||||
pub message: ::prost::alloc::string::String,
|
pub message: ::prost::alloc::string::String,
|
||||||
}
|
}
|
||||||
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct ReplaceTableValidationRequest {
|
||||||
|
#[prost(string, tag = "1")]
|
||||||
|
pub profile_name: ::prost::alloc::string::String,
|
||||||
|
#[prost(string, tag = "2")]
|
||||||
|
pub table_name: ::prost::alloc::string::String,
|
||||||
|
/// Full replacement set. Fields omitted here are removed from the stored config.
|
||||||
|
#[prost(message, repeated, tag = "3")]
|
||||||
|
pub fields: ::prost::alloc::vec::Vec<FieldValidation>,
|
||||||
|
}
|
||||||
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct ReplaceTableValidationResponse {
|
||||||
|
#[prost(bool, tag = "1")]
|
||||||
|
pub success: bool,
|
||||||
|
#[prost(string, tag = "2")]
|
||||||
|
pub message: ::prost::alloc::string::String,
|
||||||
|
}
|
||||||
/// Character length counting mode
|
/// Character length counting mode
|
||||||
#[derive(serde::Serialize, serde::Deserialize)]
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||||
@@ -167,6 +242,90 @@ impl CountMode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
|
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
|
||||||
|
#[repr(i32)]
|
||||||
|
pub enum PatternPositionKind {
|
||||||
|
Unspecified = 0,
|
||||||
|
PatternPositionSingle = 1,
|
||||||
|
PatternPositionRange = 2,
|
||||||
|
PatternPositionFrom = 3,
|
||||||
|
PatternPositionMultiple = 4,
|
||||||
|
}
|
||||||
|
impl PatternPositionKind {
|
||||||
|
/// String value of the enum field names used in the ProtoBuf definition.
|
||||||
|
///
|
||||||
|
/// The values are not transformed in any way and thus are considered stable
|
||||||
|
/// (if the ProtoBuf definition does not change) and safe for programmatic use.
|
||||||
|
pub fn as_str_name(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Self::Unspecified => "PATTERN_POSITION_KIND_UNSPECIFIED",
|
||||||
|
Self::PatternPositionSingle => "PATTERN_POSITION_SINGLE",
|
||||||
|
Self::PatternPositionRange => "PATTERN_POSITION_RANGE",
|
||||||
|
Self::PatternPositionFrom => "PATTERN_POSITION_FROM",
|
||||||
|
Self::PatternPositionMultiple => "PATTERN_POSITION_MULTIPLE",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||||
|
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
|
||||||
|
match value {
|
||||||
|
"PATTERN_POSITION_KIND_UNSPECIFIED" => Some(Self::Unspecified),
|
||||||
|
"PATTERN_POSITION_SINGLE" => Some(Self::PatternPositionSingle),
|
||||||
|
"PATTERN_POSITION_RANGE" => Some(Self::PatternPositionRange),
|
||||||
|
"PATTERN_POSITION_FROM" => Some(Self::PatternPositionFrom),
|
||||||
|
"PATTERN_POSITION_MULTIPLE" => Some(Self::PatternPositionMultiple),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
|
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
|
||||||
|
#[repr(i32)]
|
||||||
|
pub enum CharacterConstraintKind {
|
||||||
|
Unspecified = 0,
|
||||||
|
CharacterConstraintAlphabetic = 1,
|
||||||
|
CharacterConstraintNumeric = 2,
|
||||||
|
CharacterConstraintAlphanumeric = 3,
|
||||||
|
CharacterConstraintExact = 4,
|
||||||
|
CharacterConstraintOneOf = 5,
|
||||||
|
CharacterConstraintRegex = 6,
|
||||||
|
}
|
||||||
|
impl CharacterConstraintKind {
|
||||||
|
/// String value of the enum field names used in the ProtoBuf definition.
|
||||||
|
///
|
||||||
|
/// The values are not transformed in any way and thus are considered stable
|
||||||
|
/// (if the ProtoBuf definition does not change) and safe for programmatic use.
|
||||||
|
pub fn as_str_name(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Self::Unspecified => "CHARACTER_CONSTRAINT_KIND_UNSPECIFIED",
|
||||||
|
Self::CharacterConstraintAlphabetic => "CHARACTER_CONSTRAINT_ALPHABETIC",
|
||||||
|
Self::CharacterConstraintNumeric => "CHARACTER_CONSTRAINT_NUMERIC",
|
||||||
|
Self::CharacterConstraintAlphanumeric => "CHARACTER_CONSTRAINT_ALPHANUMERIC",
|
||||||
|
Self::CharacterConstraintExact => "CHARACTER_CONSTRAINT_EXACT",
|
||||||
|
Self::CharacterConstraintOneOf => "CHARACTER_CONSTRAINT_ONE_OF",
|
||||||
|
Self::CharacterConstraintRegex => "CHARACTER_CONSTRAINT_REGEX",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||||
|
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
|
||||||
|
match value {
|
||||||
|
"CHARACTER_CONSTRAINT_KIND_UNSPECIFIED" => Some(Self::Unspecified),
|
||||||
|
"CHARACTER_CONSTRAINT_ALPHABETIC" => {
|
||||||
|
Some(Self::CharacterConstraintAlphabetic)
|
||||||
|
}
|
||||||
|
"CHARACTER_CONSTRAINT_NUMERIC" => Some(Self::CharacterConstraintNumeric),
|
||||||
|
"CHARACTER_CONSTRAINT_ALPHANUMERIC" => {
|
||||||
|
Some(Self::CharacterConstraintAlphanumeric)
|
||||||
|
}
|
||||||
|
"CHARACTER_CONSTRAINT_EXACT" => Some(Self::CharacterConstraintExact),
|
||||||
|
"CHARACTER_CONSTRAINT_ONE_OF" => Some(Self::CharacterConstraintOneOf),
|
||||||
|
"CHARACTER_CONSTRAINT_REGEX" => Some(Self::CharacterConstraintRegex),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
/// Generated client implementations.
|
/// Generated client implementations.
|
||||||
pub mod table_validation_service_client {
|
pub mod table_validation_service_client {
|
||||||
#![allow(
|
#![allow(
|
||||||
@@ -178,7 +337,7 @@ pub mod table_validation_service_client {
|
|||||||
)]
|
)]
|
||||||
use tonic::codegen::*;
|
use tonic::codegen::*;
|
||||||
use tonic::codegen::http::Uri;
|
use tonic::codegen::http::Uri;
|
||||||
/// Service to fetch validations for a table
|
/// Service for storing and fetching field-validation definitions.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TableValidationServiceClient<T> {
|
pub struct TableValidationServiceClient<T> {
|
||||||
inner: tonic::client::Grpc<T>,
|
inner: tonic::client::Grpc<T>,
|
||||||
@@ -290,6 +449,7 @@ pub mod table_validation_service_client {
|
|||||||
);
|
);
|
||||||
self.inner.unary(req, path, codec).await
|
self.inner.unary(req, path, codec).await
|
||||||
}
|
}
|
||||||
|
/// Upsert a single field validation definition.
|
||||||
pub async fn update_field_validation(
|
pub async fn update_field_validation(
|
||||||
&mut self,
|
&mut self,
|
||||||
request: impl tonic::IntoRequest<super::UpdateFieldValidationRequest>,
|
request: impl tonic::IntoRequest<super::UpdateFieldValidationRequest>,
|
||||||
@@ -319,6 +479,36 @@ pub mod table_validation_service_client {
|
|||||||
);
|
);
|
||||||
self.inner.unary(req, path, codec).await
|
self.inner.unary(req, path, codec).await
|
||||||
}
|
}
|
||||||
|
/// Replace the full validation definition set for a table in one transaction.
|
||||||
|
pub async fn replace_table_validation(
|
||||||
|
&mut self,
|
||||||
|
request: impl tonic::IntoRequest<super::ReplaceTableValidationRequest>,
|
||||||
|
) -> std::result::Result<
|
||||||
|
tonic::Response<super::ReplaceTableValidationResponse>,
|
||||||
|
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(
|
||||||
|
"/komp_ac.table_validation.TableValidationService/ReplaceTableValidation",
|
||||||
|
);
|
||||||
|
let mut req = request.into_request();
|
||||||
|
req.extensions_mut()
|
||||||
|
.insert(
|
||||||
|
GrpcMethod::new(
|
||||||
|
"komp_ac.table_validation.TableValidationService",
|
||||||
|
"ReplaceTableValidation",
|
||||||
|
),
|
||||||
|
);
|
||||||
|
self.inner.unary(req, path, codec).await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Generated server implementations.
|
/// Generated server implementations.
|
||||||
@@ -341,6 +531,7 @@ pub mod table_validation_service_server {
|
|||||||
tonic::Response<super::TableValidationResponse>,
|
tonic::Response<super::TableValidationResponse>,
|
||||||
tonic::Status,
|
tonic::Status,
|
||||||
>;
|
>;
|
||||||
|
/// Upsert a single field validation definition.
|
||||||
async fn update_field_validation(
|
async fn update_field_validation(
|
||||||
&self,
|
&self,
|
||||||
request: tonic::Request<super::UpdateFieldValidationRequest>,
|
request: tonic::Request<super::UpdateFieldValidationRequest>,
|
||||||
@@ -348,8 +539,16 @@ pub mod table_validation_service_server {
|
|||||||
tonic::Response<super::UpdateFieldValidationResponse>,
|
tonic::Response<super::UpdateFieldValidationResponse>,
|
||||||
tonic::Status,
|
tonic::Status,
|
||||||
>;
|
>;
|
||||||
|
/// Replace the full validation definition set for a table in one transaction.
|
||||||
|
async fn replace_table_validation(
|
||||||
|
&self,
|
||||||
|
request: tonic::Request<super::ReplaceTableValidationRequest>,
|
||||||
|
) -> std::result::Result<
|
||||||
|
tonic::Response<super::ReplaceTableValidationResponse>,
|
||||||
|
tonic::Status,
|
||||||
|
>;
|
||||||
}
|
}
|
||||||
/// Service to fetch validations for a table
|
/// Service for storing and fetching field-validation definitions.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TableValidationServiceServer<T> {
|
pub struct TableValidationServiceServer<T> {
|
||||||
inner: Arc<T>,
|
inner: Arc<T>,
|
||||||
@@ -527,6 +726,57 @@ pub mod table_validation_service_server {
|
|||||||
};
|
};
|
||||||
Box::pin(fut)
|
Box::pin(fut)
|
||||||
}
|
}
|
||||||
|
"/komp_ac.table_validation.TableValidationService/ReplaceTableValidation" => {
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
struct ReplaceTableValidationSvc<T: TableValidationService>(
|
||||||
|
pub Arc<T>,
|
||||||
|
);
|
||||||
|
impl<
|
||||||
|
T: TableValidationService,
|
||||||
|
> tonic::server::UnaryService<super::ReplaceTableValidationRequest>
|
||||||
|
for ReplaceTableValidationSvc<T> {
|
||||||
|
type Response = super::ReplaceTableValidationResponse;
|
||||||
|
type Future = BoxFuture<
|
||||||
|
tonic::Response<Self::Response>,
|
||||||
|
tonic::Status,
|
||||||
|
>;
|
||||||
|
fn call(
|
||||||
|
&mut self,
|
||||||
|
request: tonic::Request<super::ReplaceTableValidationRequest>,
|
||||||
|
) -> Self::Future {
|
||||||
|
let inner = Arc::clone(&self.0);
|
||||||
|
let fut = async move {
|
||||||
|
<T as TableValidationService>::replace_table_validation(
|
||||||
|
&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 = ReplaceTableValidationSvc(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(
|
let mut response = http::Response::new(
|
||||||
|
|||||||
2
server
2
server
Submodule server updated: 403785118a...f828b7688a
Reference in New Issue
Block a user