new enum instead of string in proto
This commit is contained in:
2
client
2
client
Submodule client updated: 4ef069e7b1...dc88add49e
Submodule client-gui2 updated: 782877f62a...965938b510
@@ -47,12 +47,18 @@ message ReindexResponse {
|
||||
uint64 affected_tables = 2;
|
||||
}
|
||||
|
||||
enum SearchIndexOperation {
|
||||
SEARCH_INDEX_OPERATION_UNSPECIFIED = 0;
|
||||
SEARCH_INDEX_OPERATION_UPSERT = 1;
|
||||
SEARCH_INDEX_OPERATION_DELETE = 2;
|
||||
}
|
||||
|
||||
message SearchIndexError {
|
||||
int64 job_id = 1;
|
||||
string profile_name = 2;
|
||||
string table_name = 3;
|
||||
int64 row_id = 4;
|
||||
string operation = 5;
|
||||
SearchIndexOperation operation = 5;
|
||||
int32 attempts = 6;
|
||||
string last_error = 7;
|
||||
}
|
||||
|
||||
@@ -437,7 +437,7 @@ message ProfileTreeResponse {
|
||||
repeated string row_display_columns = 4;
|
||||
|
||||
// "dynamic" for user-defined tables, "system" for backend-managed tables.
|
||||
string table_kind = 5;
|
||||
ManagedTableKind table_kind = 5;
|
||||
|
||||
// True when this table is shared by every profile.
|
||||
bool global = 6;
|
||||
@@ -590,6 +590,12 @@ message GetAliasChangeHistoryResponse {
|
||||
repeated AliasChangeHistoryEntry entries = 2;
|
||||
}
|
||||
|
||||
enum ManagedTableKind {
|
||||
MANAGED_TABLE_KIND_UNSPECIFIED = 0;
|
||||
MANAGED_TABLE_KIND_DYNAMIC = 1;
|
||||
MANAGED_TABLE_KIND_SYSTEM = 2;
|
||||
}
|
||||
|
||||
// Describes a table with its columns and associated scripts.
|
||||
message TableDetail {
|
||||
string name = 1;
|
||||
@@ -598,7 +604,7 @@ message TableDetail {
|
||||
repeated ScriptInfo scripts = 4;
|
||||
repeated string row_display_columns = 6;
|
||||
map<string, ColumnBehavior> column_behaviors = 7;
|
||||
string table_kind = 8;
|
||||
ManagedTableKind table_kind = 8;
|
||||
bool global = 9;
|
||||
// Revision of this table definition for optimistic concurrency control.
|
||||
int64 row_version = 10;
|
||||
|
||||
Binary file not shown.
@@ -42,8 +42,8 @@ pub struct SearchIndexError {
|
||||
pub table_name: ::prost::alloc::string::String,
|
||||
#[prost(int64, tag = "4")]
|
||||
pub row_id: i64,
|
||||
#[prost(string, tag = "5")]
|
||||
pub operation: ::prost::alloc::string::String,
|
||||
#[prost(enumeration = "SearchIndexOperation", tag = "5")]
|
||||
pub operation: i32,
|
||||
#[prost(int32, tag = "6")]
|
||||
pub attempts: i32,
|
||||
#[prost(string, tag = "7")]
|
||||
@@ -181,6 +181,36 @@ pub struct BatchCountResponse {
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
|
||||
#[repr(i32)]
|
||||
pub enum SearchIndexOperation {
|
||||
Unspecified = 0,
|
||||
Upsert = 1,
|
||||
Delete = 2,
|
||||
}
|
||||
impl SearchIndexOperation {
|
||||
/// 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 => "SEARCH_INDEX_OPERATION_UNSPECIFIED",
|
||||
Self::Upsert => "SEARCH_INDEX_OPERATION_UPSERT",
|
||||
Self::Delete => "SEARCH_INDEX_OPERATION_DELETE",
|
||||
}
|
||||
}
|
||||
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
|
||||
match value {
|
||||
"SEARCH_INDEX_OPERATION_UNSPECIFIED" => Some(Self::Unspecified),
|
||||
"SEARCH_INDEX_OPERATION_UPSERT" => Some(Self::Upsert),
|
||||
"SEARCH_INDEX_OPERATION_DELETE" => Some(Self::Delete),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
|
||||
#[repr(i32)]
|
||||
pub enum MatchMode {
|
||||
Unspecified = 0,
|
||||
Fuzzy = 1,
|
||||
|
||||
@@ -389,8 +389,8 @@ pub mod profile_tree_response {
|
||||
::prost::alloc::string::String,
|
||||
>,
|
||||
/// "dynamic" for user-defined tables, "system" for backend-managed tables.
|
||||
#[prost(string, tag = "5")]
|
||||
pub table_kind: ::prost::alloc::string::String,
|
||||
#[prost(enumeration = "super::ManagedTableKind", tag = "5")]
|
||||
pub table_kind: i32,
|
||||
/// True when this table is shared by every profile.
|
||||
#[prost(bool, tag = "6")]
|
||||
pub global: bool,
|
||||
@@ -625,8 +625,8 @@ pub struct TableDetail {
|
||||
::prost::alloc::string::String,
|
||||
ColumnBehavior,
|
||||
>,
|
||||
#[prost(string, tag = "8")]
|
||||
pub table_kind: ::prost::alloc::string::String,
|
||||
#[prost(enumeration = "ManagedTableKind", tag = "8")]
|
||||
pub table_kind: i32,
|
||||
#[prost(bool, tag = "9")]
|
||||
pub global: bool,
|
||||
/// Revision of this table definition for optimistic concurrency control.
|
||||
@@ -1156,6 +1156,36 @@ impl AliasChangeKind {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
|
||||
#[repr(i32)]
|
||||
pub enum ManagedTableKind {
|
||||
Unspecified = 0,
|
||||
Dynamic = 1,
|
||||
System = 2,
|
||||
}
|
||||
impl ManagedTableKind {
|
||||
/// 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 => "MANAGED_TABLE_KIND_UNSPECIFIED",
|
||||
Self::Dynamic => "MANAGED_TABLE_KIND_DYNAMIC",
|
||||
Self::System => "MANAGED_TABLE_KIND_SYSTEM",
|
||||
}
|
||||
}
|
||||
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
|
||||
match value {
|
||||
"MANAGED_TABLE_KIND_UNSPECIFIED" => Some(Self::Unspecified),
|
||||
"MANAGED_TABLE_KIND_DYNAMIC" => Some(Self::Dynamic),
|
||||
"MANAGED_TABLE_KIND_SYSTEM" => Some(Self::System),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
/// How a column type is spelled in ColumnDefinition.field_type.
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
|
||||
|
||||
2
server
2
server
Submodule server updated: c51ead9a19...8dc3686366
@@ -112,12 +112,13 @@ pub(crate) async fn load_page(
|
||||
// The profile's ledger accounts are not a link target of their own: an
|
||||
// ACCOUNTING column is how a row is posted to one.
|
||||
.filter(|table| table.name != crate::schema::LEDGER_ACCOUNTS_TABLE)
|
||||
.map(|table| RelationTableOption {
|
||||
.map(|table| Ok(RelationTableOption {
|
||||
name: table.name,
|
||||
global: table.global,
|
||||
system: table.table_kind == "system",
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
system: table_scope::table_kind(table.table_kind).map_err(LoadError::Backend)?
|
||||
== crate::definitions::table_definition::ManagedTableKind::System,
|
||||
}))
|
||||
.collect::<Result<Vec<_>, LoadError>>()?;
|
||||
|
||||
// Every table the new one would sit beside holds its name — including the
|
||||
// shared ones, which exist in every profile, and including in a profile
|
||||
|
||||
@@ -101,7 +101,7 @@ pub(crate) async fn load_admin_page(
|
||||
.map(|tables| {
|
||||
tables
|
||||
.into_iter()
|
||||
.map(|table| TableView {
|
||||
.map(|table| Ok(TableView {
|
||||
name: table.name,
|
||||
// One entry per link, named by the column carrying it, so a
|
||||
// table pointing at one target twice reads as two links.
|
||||
@@ -113,10 +113,11 @@ pub(crate) async fn load_admin_page(
|
||||
})
|
||||
.collect(),
|
||||
row_display_columns: table.row_display_columns,
|
||||
table_kind: table.table_kind,
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
table_kind: table_scope::table_kind(table.table_kind).map_err(LoadError::Backend)?,
|
||||
}))
|
||||
.collect::<Result<Vec<_>, LoadError>>()
|
||||
})
|
||||
.transpose()?
|
||||
.unwrap_or_default();
|
||||
|
||||
let selected_table = (!selection.table.is_empty()).then_some(selection.table);
|
||||
|
||||
@@ -84,14 +84,14 @@ pub(crate) struct TableView {
|
||||
pub name: String,
|
||||
pub depends_on: Vec<String>,
|
||||
pub row_display_columns: Vec<String>,
|
||||
pub table_kind: String,
|
||||
pub table_kind: crate::definitions::table_definition::ManagedTableKind,
|
||||
}
|
||||
|
||||
impl TableView {
|
||||
/// System tables are backend-managed: the server refuses every structural
|
||||
/// write on them, so the pane offers none of the action links for one.
|
||||
pub(crate) fn is_system(&self) -> bool {
|
||||
self.table_kind == "system"
|
||||
self.table_kind == crate::definitions::table_definition::ManagedTableKind::System
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@ mod tests {
|
||||
name: "invoice".to_string(),
|
||||
depends_on: Vec::new(),
|
||||
row_display_columns: vec!["number".to_string()],
|
||||
table_kind: "dynamic".to_string(),
|
||||
table_kind: crate::definitions::table_definition::ManagedTableKind::Dynamic,
|
||||
}],
|
||||
selected_table: Some("invoice".to_string()),
|
||||
columns: Vec::new(),
|
||||
@@ -195,7 +195,7 @@ mod tests {
|
||||
name: "currencies".to_string(),
|
||||
depends_on: Vec::new(),
|
||||
row_display_columns: vec!["code".to_string()],
|
||||
table_kind: "dynamic".to_string(),
|
||||
table_kind: crate::definitions::table_definition::ManagedTableKind::Dynamic,
|
||||
}],
|
||||
selected_table: Some("currencies".to_string()),
|
||||
columns: Vec::new(),
|
||||
|
||||
@@ -146,9 +146,9 @@ pub(crate) async fn load_page(
|
||||
} else {
|
||||
table_scope::linkable_tables(&tree.profiles, &catalog_tables, &inputs.selection.profile)
|
||||
};
|
||||
let summary = |table: crate::definitions::table_definition::profile_tree_response::Table| TableSummary {
|
||||
let summary = |table: crate::definitions::table_definition::profile_tree_response::Table| -> Result<TableSummary, LoadError> { Ok(TableSummary {
|
||||
name: table.name,
|
||||
table_kind: table.table_kind,
|
||||
table_kind: table_scope::table_kind(table.table_kind).map_err(LoadError::Backend)?,
|
||||
global: table.global,
|
||||
// One entry per link, named by the column carrying it, so a table
|
||||
// pointing at one target twice reads as two links.
|
||||
@@ -157,9 +157,9 @@ pub(crate) async fn load_page(
|
||||
.into_iter()
|
||||
.map(|dependency| format!("{} ({})", dependency.table_name, dependency.column_name))
|
||||
.collect(),
|
||||
};
|
||||
let tables = selected_tables.into_iter().map(summary).collect::<Vec<_>>();
|
||||
let link_targets = link_targets.into_iter().map(summary).collect::<Vec<_>>();
|
||||
}) };
|
||||
let tables = selected_tables.into_iter().map(summary).collect::<Result<Vec<_>, _>>()?;
|
||||
let link_targets = link_targets.into_iter().map(summary).collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
// A table the scope does not hold is dropped rather than acted on. It is
|
||||
// said out loud, though: dropping it in silence is what left the panel
|
||||
|
||||
@@ -67,7 +67,7 @@ impl Selection {
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct TableSummary {
|
||||
pub name: String,
|
||||
pub table_kind: String,
|
||||
pub table_kind: crate::definitions::table_definition::ManagedTableKind,
|
||||
pub global: bool,
|
||||
pub depends_on: Vec<String>,
|
||||
}
|
||||
@@ -76,7 +76,7 @@ impl TableSummary {
|
||||
/// System tables are backend-managed: the server refuses every write below
|
||||
/// on them, so the workspace does not offer the panels either.
|
||||
pub(crate) fn is_system(&self) -> bool {
|
||||
self.table_kind == "system"
|
||||
self.table_kind == crate::definitions::table_definition::ManagedTableKind::System
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -247,10 +247,10 @@ mod tests {
|
||||
schema::ColumnDraft,
|
||||
};
|
||||
|
||||
fn table(name: &str, kind: &str) -> TableSummary {
|
||||
fn table(name: &str, kind: crate::definitions::table_definition::ManagedTableKind) -> TableSummary {
|
||||
TableSummary {
|
||||
name: name.to_string(),
|
||||
table_kind: kind.to_string(),
|
||||
table_kind: kind,
|
||||
global: false,
|
||||
depends_on: Vec::new(),
|
||||
}
|
||||
@@ -268,8 +268,8 @@ mod tests {
|
||||
profile: "billing".to_string(),
|
||||
table: "invoice".to_string(),
|
||||
},
|
||||
tables: vec![table("invoice", "dynamic"), table("ledger_accounts", "system")],
|
||||
link_targets: vec![table("invoice", "dynamic"), table("ledger_accounts", "system")],
|
||||
tables: vec![table("invoice", crate::definitions::table_definition::ManagedTableKind::Dynamic), table("ledger_accounts", crate::definitions::table_definition::ManagedTableKind::System)],
|
||||
link_targets: vec![table("invoice", crate::definitions::table_definition::ManagedTableKind::Dynamic), table("ledger_accounts", crate::definitions::table_definition::ManagedTableKind::System)],
|
||||
detail: Some(TableDetailView {
|
||||
id: 7,
|
||||
row_version: 1,
|
||||
@@ -364,7 +364,7 @@ mod tests {
|
||||
};
|
||||
state.tables = vec![TableSummary {
|
||||
name: "currencies".to_string(),
|
||||
table_kind: "dynamic".to_string(),
|
||||
table_kind: crate::definitions::table_definition::ManagedTableKind::Dynamic,
|
||||
global: true,
|
||||
depends_on: Vec::new(),
|
||||
}];
|
||||
@@ -598,12 +598,12 @@ mod tests {
|
||||
state.columns.type_input = "link".to_string();
|
||||
// The link targets are their own list: a profile's table may point at
|
||||
// a shared one, which is not among the profile's own tables.
|
||||
state.link_targets.push(table("customer", "dynamic"));
|
||||
state.link_targets.push(table("customer", crate::definitions::table_definition::ManagedTableKind::Dynamic));
|
||||
state.link_targets.push(TableSummary {
|
||||
global: true,
|
||||
..table("currencies", "dynamic")
|
||||
..table("currencies", crate::definitions::table_definition::ManagedTableKind::Dynamic)
|
||||
});
|
||||
state.link_targets.push(table("audit_log", "system"));
|
||||
state.link_targets.push(table("audit_log", crate::definitions::table_definition::ManagedTableKind::System));
|
||||
|
||||
let html = render_column_panel(&state);
|
||||
|
||||
|
||||
@@ -13,6 +13,14 @@
|
||||
//! profile's own tables are the tree's. Neither is derived from the other.
|
||||
|
||||
use crate::definitions::table_definition::profile_tree_response::{Profile, Table};
|
||||
use crate::definitions::table_definition::ManagedTableKind;
|
||||
|
||||
pub(crate) fn table_kind(value: i32) -> Result<ManagedTableKind, String> {
|
||||
match ManagedTableKind::try_from(value) {
|
||||
Ok(kind @ (ManagedTableKind::Dynamic | ManagedTableKind::System)) => Ok(kind),
|
||||
_ => Err(format!("Invalid managed table kind: {value}")),
|
||||
}
|
||||
}
|
||||
|
||||
/// The tables of the global scope: the catalog for `profile_name: None`, which
|
||||
/// is every shared table in the deployment, whether or not any profile exists
|
||||
@@ -74,7 +82,7 @@ pub(crate) mod tests {
|
||||
name: name.to_string(),
|
||||
depends_on: Vec::new(),
|
||||
row_display_columns: Vec::new(),
|
||||
table_kind: "dynamic".to_string(),
|
||||
table_kind: ManagedTableKind::Dynamic.into(),
|
||||
global,
|
||||
profile_name: if global {
|
||||
SHARED_PROFILE.to_string()
|
||||
|
||||
Reference in New Issue
Block a user