row display column
This commit is contained in:
@@ -5,7 +5,7 @@ resolver = "3"
|
|||||||
[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.8.23"
|
version = "0.8.24"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
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
client
2
client
Submodule client updated: 405182ec8d...b56c2179dd
@@ -32,6 +32,9 @@ message SearchResponse {
|
|||||||
float score = 2;
|
float score = 2;
|
||||||
string content_json = 3;
|
string content_json = 3;
|
||||||
string table_name = 4;
|
string table_name = 4;
|
||||||
|
// Configured human-readable value for this row.
|
||||||
|
string row_display_value = 5;
|
||||||
|
string row_display_column = 6;
|
||||||
}
|
}
|
||||||
repeated Hit hits = 1;
|
repeated Hit hits = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ message Search2Response {
|
|||||||
int64 id = 1;
|
int64 id = 1;
|
||||||
string content_json = 2; // No score - this is SQL-based
|
string content_json = 2; // No score - this is SQL-based
|
||||||
optional string match_info = 3; // Info about which columns matched
|
optional string match_info = 3; // Info about which columns matched
|
||||||
|
string row_display_value = 4; // Configured human-readable value for this row
|
||||||
|
string row_display_column = 5;
|
||||||
}
|
}
|
||||||
repeated Hit hits = 1;
|
repeated Hit hits = 1;
|
||||||
int32 total_count = 2; // Total matching records (for pagination)
|
int32 total_count = 2; // Total matching records (for pagination)
|
||||||
|
|||||||
@@ -80,6 +80,10 @@ message PostTableDefinitionRequest {
|
|||||||
|
|
||||||
// ISO-4217 base currency used by every MONEY column in this table.
|
// ISO-4217 base currency used by every MONEY column in this table.
|
||||||
string base_currency = 6;
|
string base_currency = 6;
|
||||||
|
|
||||||
|
// Column whose value identifies a row to users in pickers. "id" is always
|
||||||
|
// valid; otherwise this must name one of the user-defined columns above.
|
||||||
|
string row_display_column = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Defines append-only column additions for an existing table.
|
// Defines append-only column additions for an existing table.
|
||||||
@@ -157,6 +161,9 @@ message ProfileTreeResponse {
|
|||||||
|
|
||||||
// Other tables this one references (based on link definitions only).
|
// Other tables this one references (based on link definitions only).
|
||||||
repeated string depends_on = 3;
|
repeated string depends_on = 3;
|
||||||
|
|
||||||
|
// Column whose value is used as the human-readable row label.
|
||||||
|
string row_display_column = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Profile (schema) entry.
|
// Profile (schema) entry.
|
||||||
@@ -231,6 +238,7 @@ message TableDetail {
|
|||||||
repeated ColumnDefinition columns = 3;
|
repeated ColumnDefinition columns = 3;
|
||||||
repeated ScriptInfo scripts = 4;
|
repeated ScriptInfo scripts = 4;
|
||||||
string base_currency = 5;
|
string base_currency = 5;
|
||||||
|
string row_display_column = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A script that targets a specific column in a table.
|
// A script that targets a specific column in a table.
|
||||||
|
|||||||
@@ -241,6 +241,11 @@ message GetTableDataResponse {
|
|||||||
// All values are returned as TEXT via col::TEXT and COALESCEed to empty string
|
// All values are returned as TEXT via col::TEXT and COALESCEed to empty string
|
||||||
// (NULL becomes ""). The row is returned only if deleted = FALSE.
|
// (NULL becomes ""). The row is returned only if deleted = FALSE.
|
||||||
map<string, string> data = 1;
|
map<string, string> data = 1;
|
||||||
|
|
||||||
|
// Configured human-readable value for this row. Empty when that column is
|
||||||
|
// NULL/empty; clients should then visibly fall back to the row id.
|
||||||
|
string row_display_value = 2;
|
||||||
|
string row_display_column = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count non-deleted rows.
|
// Count non-deleted rows.
|
||||||
|
|||||||
Binary file not shown.
@@ -41,6 +41,11 @@ pub mod search_response {
|
|||||||
pub content_json: ::prost::alloc::string::String,
|
pub content_json: ::prost::alloc::string::String,
|
||||||
#[prost(string, tag = "4")]
|
#[prost(string, tag = "4")]
|
||||||
pub table_name: ::prost::alloc::string::String,
|
pub table_name: ::prost::alloc::string::String,
|
||||||
|
/// Configured human-readable value for this row.
|
||||||
|
#[prost(string, tag = "5")]
|
||||||
|
pub row_display_value: ::prost::alloc::string::String,
|
||||||
|
#[prost(string, tag = "6")]
|
||||||
|
pub row_display_column: ::prost::alloc::string::String,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
|
||||||
|
|||||||
@@ -49,6 +49,11 @@ pub mod search2_response {
|
|||||||
/// Info about which columns matched
|
/// Info about which columns matched
|
||||||
#[prost(string, optional, tag = "3")]
|
#[prost(string, optional, tag = "3")]
|
||||||
pub match_info: ::core::option::Option<::prost::alloc::string::String>,
|
pub match_info: ::core::option::Option<::prost::alloc::string::String>,
|
||||||
|
/// Configured human-readable value for this row
|
||||||
|
#[prost(string, tag = "4")]
|
||||||
|
pub row_display_value: ::prost::alloc::string::String,
|
||||||
|
#[prost(string, tag = "5")]
|
||||||
|
pub row_display_column: ::prost::alloc::string::String,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ pub struct PostTableDefinitionRequest {
|
|||||||
/// ISO-4217 base currency used by every MONEY column in this table.
|
/// ISO-4217 base currency used by every MONEY column in this table.
|
||||||
#[prost(string, tag = "6")]
|
#[prost(string, tag = "6")]
|
||||||
pub base_currency: ::prost::alloc::string::String,
|
pub base_currency: ::prost::alloc::string::String,
|
||||||
|
/// Column whose value identifies a row to users in pickers. "id" is always
|
||||||
|
/// valid; otherwise this must name one of the user-defined columns above.
|
||||||
|
#[prost(string, tag = "7")]
|
||||||
|
pub row_display_column: ::prost::alloc::string::String,
|
||||||
}
|
}
|
||||||
/// Defines append-only column additions for an existing table.
|
/// Defines append-only column additions for an existing table.
|
||||||
#[derive(serde::Serialize, serde::Deserialize)]
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
@@ -129,6 +133,9 @@ pub mod profile_tree_response {
|
|||||||
/// Other tables this one references (based on link definitions only).
|
/// Other tables this one references (based on link definitions only).
|
||||||
#[prost(string, repeated, tag = "3")]
|
#[prost(string, repeated, tag = "3")]
|
||||||
pub depends_on: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
|
pub depends_on: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
|
||||||
|
/// Column whose value is used as the human-readable row label.
|
||||||
|
#[prost(string, tag = "4")]
|
||||||
|
pub row_display_column: ::prost::alloc::string::String,
|
||||||
}
|
}
|
||||||
/// Profile (schema) entry.
|
/// Profile (schema) entry.
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
@@ -231,6 +238,8 @@ pub struct TableDetail {
|
|||||||
pub scripts: ::prost::alloc::vec::Vec<ScriptInfo>,
|
pub scripts: ::prost::alloc::vec::Vec<ScriptInfo>,
|
||||||
#[prost(string, tag = "5")]
|
#[prost(string, tag = "5")]
|
||||||
pub base_currency: ::prost::alloc::string::String,
|
pub base_currency: ::prost::alloc::string::String,
|
||||||
|
#[prost(string, tag = "6")]
|
||||||
|
pub row_display_column: ::prost::alloc::string::String,
|
||||||
}
|
}
|
||||||
/// A script that targets a specific column in a table.
|
/// A script that targets a specific column in a table.
|
||||||
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
|
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
|
||||||
|
|||||||
@@ -186,6 +186,12 @@ pub struct GetTableDataResponse {
|
|||||||
::prost::alloc::string::String,
|
::prost::alloc::string::String,
|
||||||
::prost::alloc::string::String,
|
::prost::alloc::string::String,
|
||||||
>,
|
>,
|
||||||
|
/// Configured human-readable value for this row. Empty when that column is
|
||||||
|
/// NULL/empty; clients should then visibly fall back to the row id.
|
||||||
|
#[prost(string, tag = "2")]
|
||||||
|
pub row_display_value: ::prost::alloc::string::String,
|
||||||
|
#[prost(string, tag = "3")]
|
||||||
|
pub row_display_column: ::prost::alloc::string::String,
|
||||||
}
|
}
|
||||||
/// Count non-deleted rows.
|
/// Count non-deleted rows.
|
||||||
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
|
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
|
||||||
|
|||||||
@@ -461,6 +461,26 @@ async fn table_physical_to_display_map(
|
|||||||
Ok(mapping)
|
Ok(mapping)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn table_row_display_column(
|
||||||
|
pool: &PgPool,
|
||||||
|
profile_name: &str,
|
||||||
|
table_name: &str,
|
||||||
|
) -> Result<String, Status> {
|
||||||
|
sqlx::query_scalar(
|
||||||
|
r#"
|
||||||
|
SELECT td.row_display_column
|
||||||
|
FROM schemas s
|
||||||
|
JOIN table_definitions td ON td.schema_id = s.id
|
||||||
|
WHERE s.name = $1 AND td.table_name = $2
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.bind(profile_name)
|
||||||
|
.bind(table_name)
|
||||||
|
.fetch_one(pool)
|
||||||
|
.await
|
||||||
|
.map_err(|e| Status::internal(format!("Row display column lookup failed: {}", e)))
|
||||||
|
}
|
||||||
|
|
||||||
fn remap_json_to_display_names(
|
fn remap_json_to_display_names(
|
||||||
value: serde_json::Value,
|
value: serde_json::Value,
|
||||||
physical_to_display: &HashMap<String, String>,
|
physical_to_display: &HashMap<String, String>,
|
||||||
@@ -478,6 +498,15 @@ fn remap_json_to_display_names(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn row_display_value(value: &serde_json::Value, column: &str) -> String {
|
||||||
|
match value.get(column) {
|
||||||
|
Some(serde_json::Value::String(value)) => value.clone(),
|
||||||
|
Some(serde_json::Value::Number(value)) => value.to_string(),
|
||||||
|
Some(serde_json::Value::Bool(value)) => value.to_string(),
|
||||||
|
_ => String::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn fetch_latest_rows(
|
async fn fetch_latest_rows(
|
||||||
pool: &PgPool,
|
pool: &PgPool,
|
||||||
profile_name: &str,
|
profile_name: &str,
|
||||||
@@ -486,6 +515,7 @@ async fn fetch_latest_rows(
|
|||||||
offset: usize,
|
offset: usize,
|
||||||
) -> Result<Vec<Hit>, Status> {
|
) -> Result<Vec<Hit>, Status> {
|
||||||
let physical_to_display = table_physical_to_display_map(pool, profile_name, table_name).await?;
|
let physical_to_display = table_physical_to_display_map(pool, profile_name, table_name).await?;
|
||||||
|
let display_column = table_row_display_column(pool, profile_name, table_name).await?;
|
||||||
let sql = format!(
|
let sql = format!(
|
||||||
"SELECT id, to_jsonb(t) AS data FROM {} t WHERE deleted = FALSE ORDER BY id DESC LIMIT $1 OFFSET $2",
|
"SELECT id, to_jsonb(t) AS data FROM {} t WHERE deleted = FALSE ORDER BY id DESC LIMIT $1 OFFSET $2",
|
||||||
qualify_profile_table(profile_name, table_name)
|
qualify_profile_table(profile_name, table_name)
|
||||||
@@ -504,11 +534,14 @@ async fn fetch_latest_rows(
|
|||||||
let id: i64 = row.try_get("id").unwrap_or_default();
|
let id: i64 = row.try_get("id").unwrap_or_default();
|
||||||
let json_data: serde_json::Value = row.try_get("data").unwrap_or_default();
|
let json_data: serde_json::Value = row.try_get("data").unwrap_or_default();
|
||||||
let json_data = remap_json_to_display_names(json_data, &physical_to_display);
|
let json_data = remap_json_to_display_names(json_data, &physical_to_display);
|
||||||
|
let row_display_value = row_display_value(&json_data, &display_column);
|
||||||
Hit {
|
Hit {
|
||||||
id,
|
id,
|
||||||
score: 0.0,
|
score: 0.0,
|
||||||
content_json: json_data.to_string(),
|
content_json: json_data.to_string(),
|
||||||
table_name: table_name.to_string(),
|
table_name: table_name.to_string(),
|
||||||
|
row_display_value,
|
||||||
|
row_display_column: display_column.clone(),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect())
|
.collect())
|
||||||
@@ -587,11 +620,12 @@ async fn run_search(
|
|||||||
.push(*pg_id);
|
.push(*pg_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut content_map: HashMap<(String, i64), String> = HashMap::new();
|
let mut content_map: HashMap<(String, i64), (String, String, String)> = HashMap::new();
|
||||||
for (table_name, pg_ids) in ids_by_table {
|
for (table_name, pg_ids) in ids_by_table {
|
||||||
validate_identifier(&table_name, "table_name")?;
|
validate_identifier(&table_name, "table_name")?;
|
||||||
let physical_to_display =
|
let physical_to_display =
|
||||||
table_physical_to_display_map(pool, profile_name, &table_name).await?;
|
table_physical_to_display_map(pool, profile_name, &table_name).await?;
|
||||||
|
let display_column = table_row_display_column(pool, profile_name, &table_name).await?;
|
||||||
let sql = format!(
|
let sql = format!(
|
||||||
"SELECT id, to_jsonb(t) AS data FROM {} t WHERE deleted = FALSE AND id = ANY($1)",
|
"SELECT id, to_jsonb(t) AS data FROM {} t WHERE deleted = FALSE AND id = ANY($1)",
|
||||||
qualify_profile_table(profile_name, &table_name)
|
qualify_profile_table(profile_name, &table_name)
|
||||||
@@ -607,7 +641,11 @@ async fn run_search(
|
|||||||
let id: i64 = row.try_get("id").unwrap_or_default();
|
let id: i64 = row.try_get("id").unwrap_or_default();
|
||||||
let json_data: serde_json::Value = row.try_get("data").unwrap_or_default();
|
let json_data: serde_json::Value = row.try_get("data").unwrap_or_default();
|
||||||
let json_data = remap_json_to_display_names(json_data, &physical_to_display);
|
let json_data = remap_json_to_display_names(json_data, &physical_to_display);
|
||||||
content_map.insert((table_name.clone(), id), json_data.to_string());
|
let display_value = row_display_value(&json_data, &display_column);
|
||||||
|
content_map.insert(
|
||||||
|
(table_name.clone(), id),
|
||||||
|
(json_data.to_string(), display_value, display_column.clone()),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -616,11 +654,13 @@ async fn run_search(
|
|||||||
.filter_map(|(score, pg_id, table_name)| {
|
.filter_map(|(score, pg_id, table_name)| {
|
||||||
content_map
|
content_map
|
||||||
.get(&(table_name.clone(), pg_id))
|
.get(&(table_name.clone(), pg_id))
|
||||||
.map(|content_json| Hit {
|
.map(|(content_json, row_display_value, row_display_column)| Hit {
|
||||||
id: pg_id,
|
id: pg_id,
|
||||||
score,
|
score,
|
||||||
content_json: content_json.clone(),
|
content_json: content_json.clone(),
|
||||||
table_name,
|
table_name,
|
||||||
|
row_display_value: row_display_value.clone(),
|
||||||
|
row_display_column: row_display_column.clone(),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect())
|
.collect())
|
||||||
|
|||||||
2
server
2
server
Submodule server updated: 70a5f58580...e260f77907
Reference in New Issue
Block a user