diff --git a/client b/client index d76107b4..278e3a63 160000 --- a/client +++ b/client @@ -1 +1 @@ -Subproject commit d76107b4c4b89c78f070e27725d2530c9c89cd8b +Subproject commit 278e3a6319b01bd25de7fd5138ee805bd248cc10 diff --git a/common/proto/table_definition.proto b/common/proto/table_definition.proto index 705caedd..575cf6ed 100644 --- a/common/proto/table_definition.proto +++ b/common/proto/table_definition.proto @@ -362,18 +362,69 @@ message DeleteTableResponse { string message = 2; } -// Response listing every column type a table may declare. +// How a column type is spelled in ColumnDefinition.field_type. +enum ColumnTypeSpelling { + // The name is the whole spelling: "text", "money", "gtin_13". + COLUMN_TYPE_SPELLING_BARE = 0; + + // The name takes a precision and a scale: "decimal(12,3)". Precision must be + // at least 1 and scale no greater than precision; neither may carry a sign, + // a decimal point, or leading zeros. + COLUMN_TYPE_SPELLING_DECIMAL = 1; +} + +// Response describing the whole column-type vocabulary. +// +// This is the authority a client builds its column-type picker from: every rule +// a client would otherwise hardcode about what a type means is a field here. The +// list covers types clients may NOT declare as well (see `declarable`), so that +// the same call also explains the types GetProfileDetails reports back for +// server-generated companion columns. message ListColumnTypesResponse { - // One declared column type and the SQL type it maps to. + // One column type and everything a client needs to know to offer it. message ColumnType { // Logical column type (e.g. "money", "instant"). Passed to the server as - // ColumnDefinition.field_type. + // ColumnDefinition.field_type — see `spelling`, which is what says whether + // this name is the whole spelling. string name = 1; // Underlying PostgreSQL type the logical type maps to (e.g. "NUMERIC"). + // Empty when `compound` is true. For COLUMN_TYPE_SPELLING_DECIMAL this is + // the unparameterised type; the declared precision and scale are appended. string sql_type = 2; + + // False for types the server generates on its own and rejects when a client + // declares them: the phone and IBAN companions, and the accounting-transfer + // connectors. A column-type picker must offer only declarable types. + bool declarable = 3; + + // True when the type is a definition row rather than a column: it expands + // into several schema-managed companion columns and no column of this name + // survives. A compound type can therefore never be indexed, never be a row + // display column, and has no single sql_type of its own. + bool compound = 4; + + // Whether `name` is the whole spelling or takes arguments. + ColumnTypeSpelling spelling = 5; + + // Whether ColumnDefinition.currency is required. Currency is rejected on + // every type where this is false. + bool requires_currency = 6; + + // True when the type may only be chosen while the table is being created. + // AddTableColumns rejects these, because they bring schema-managed columns + // that cannot be bolted onto a table that already exists. + bool creation_only = 7; + + // Whether ColumnDefinition.quantity_ledger may be set on this type. + bool allows_quantity_ledger = 8; + + // Optional name grouping several types a client offers behind one choice — + // "temporal" for the date and time types, "gtin" for the GTIN lengths. + // Empty when the type stands on its own. + string group = 9; } - // All declared column types. + // Every column type, declarable or not, ordered by name. repeated ColumnType column_types = 1; } diff --git a/common/src/proto/descriptor.bin b/common/src/proto/descriptor.bin index 0f2d9828..33e504fd 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 9fb8e351..51c043d4 100644 --- a/common/src/proto/komp_ac.table_definition.rs +++ b/common/src/proto/komp_ac.table_definition.rs @@ -389,25 +389,65 @@ pub struct DeleteTableResponse { #[prost(string, tag = "2")] pub message: ::prost::alloc::string::String, } -/// Response listing every column type a table may declare. +/// Response describing the whole column-type vocabulary. +/// +/// This is the authority a client builds its column-type picker from: every rule +/// a client would otherwise hardcode about what a type means is a field here. The +/// list covers types clients may NOT declare as well (see `declarable`), so that +/// the same call also explains the types GetProfileDetails reports back for +/// server-generated companion columns. #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListColumnTypesResponse { - /// All declared column types. + /// Every column type, declarable or not, ordered by name. #[prost(message, repeated, tag = "1")] pub column_types: ::prost::alloc::vec::Vec, } /// Nested message and enum types in `ListColumnTypesResponse`. pub mod list_column_types_response { - /// One declared column type and the SQL type it maps to. + /// One column type and everything a client needs to know to offer it. #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct ColumnType { /// Logical column type (e.g. "money", "instant"). Passed to the server as - /// ColumnDefinition.field_type. + /// ColumnDefinition.field_type — see `spelling`, which is what says whether + /// this name is the whole spelling. #[prost(string, tag = "1")] pub name: ::prost::alloc::string::String, /// Underlying PostgreSQL type the logical type maps to (e.g. "NUMERIC"). + /// Empty when `compound` is true. For COLUMN_TYPE_SPELLING_DECIMAL this is + /// the unparameterised type; the declared precision and scale are appended. #[prost(string, tag = "2")] pub sql_type: ::prost::alloc::string::String, + /// False for types the server generates on its own and rejects when a client + /// declares them: the phone and IBAN companions, and the accounting-transfer + /// connectors. A column-type picker must offer only declarable types. + #[prost(bool, tag = "3")] + pub declarable: bool, + /// True when the type is a definition row rather than a column: it expands + /// into several schema-managed companion columns and no column of this name + /// survives. A compound type can therefore never be indexed, never be a row + /// display column, and has no single sql_type of its own. + #[prost(bool, tag = "4")] + pub compound: bool, + /// Whether `name` is the whole spelling or takes arguments. + #[prost(enumeration = "super::ColumnTypeSpelling", tag = "5")] + pub spelling: i32, + /// Whether ColumnDefinition.currency is required. Currency is rejected on + /// every type where this is false. + #[prost(bool, tag = "6")] + pub requires_currency: bool, + /// True when the type may only be chosen while the table is being created. + /// AddTableColumns rejects these, because they bring schema-managed columns + /// that cannot be bolted onto a table that already exists. + #[prost(bool, tag = "7")] + pub creation_only: bool, + /// Whether ColumnDefinition.quantity_ledger may be set on this type. + #[prost(bool, tag = "8")] + pub allows_quantity_ledger: bool, + /// Optional name grouping several types a client offers behind one choice — + /// "temporal" for the date and time types, "gtin" for the GTIN lengths. + /// Empty when the type stands on its own. + #[prost(string, tag = "9")] + pub group: ::prost::alloc::string::String, } } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] @@ -436,6 +476,37 @@ impl MoneyRounding { } } } +/// How a column type is spelled in ColumnDefinition.field_type. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum ColumnTypeSpelling { + /// The name is the whole spelling: "text", "money", "gtin_13". + Bare = 0, + /// The name takes a precision and a scale: "decimal(12,3)". Precision must be + /// at least 1 and scale no greater than precision; neither may carry a sign, + /// a decimal point, or leading zeros. + Decimal = 1, +} +impl ColumnTypeSpelling { + /// 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::Bare => "COLUMN_TYPE_SPELLING_BARE", + Self::Decimal => "COLUMN_TYPE_SPELLING_DECIMAL", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "COLUMN_TYPE_SPELLING_BARE" => Some(Self::Bare), + "COLUMN_TYPE_SPELLING_DECIMAL" => Some(Self::Decimal), + _ => None, + } + } +} /// Generated client implementations. pub mod table_definition_client { #![allow( diff --git a/server b/server index 0a685313..cb9906ac 160000 --- a/server +++ b/server @@ -1 +1 @@ -Subproject commit 0a685313f4b134a6b86d864b7e54a9c3e4041565 +Subproject commit cb9906ac3e8a06b023ba8869ef502e81e90ea46c diff --git a/tui-canvas b/tui-canvas index eca3d629..a391929f 160000 --- a/tui-canvas +++ b/tui-canvas @@ -1 +1 @@ -Subproject commit eca3d6294feb8a08cd1946b134f93ff05de4722e +Subproject commit a391929f8f2a6cbe4de729992df1400ec201b91b diff --git a/tui-pages b/tui-pages index 1a33d6d8..7648522b 160000 --- a/tui-pages +++ b/tui-pages @@ -1 +1 @@ -Subproject commit 1a33d6d8dff878c0d882c01484b9e66c8c1a8a6a +Subproject commit 7648522be1ed41bab8dd0d2acb155ac8b7dc0b0e