optimization on the client steel scripts + fixed proto comments
This commit is contained in:
@@ -3,7 +3,6 @@ syntax = "proto3";
|
||||
package komp_ac.adresar;
|
||||
|
||||
import "common.proto";
|
||||
// import "table_structure.proto";
|
||||
|
||||
service Adresar {
|
||||
rpc PostAdresar(PostAdresarRequest) returns (AdresarResponse);
|
||||
|
||||
@@ -55,7 +55,7 @@ message ExecuteAnalyticsQueryRequest {
|
||||
// Exactly one read-only SELECT query. Table and column names are public aliases.
|
||||
string sql = 2;
|
||||
|
||||
// Optional result cap. Zero uses the server default; the server maximum still applies.
|
||||
// Result cap. Zero uses the server default; the server maximum still applies.
|
||||
uint32 max_rows = 3;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ message Search2Request {
|
||||
string profile_name = 1;
|
||||
string table_name = 2;
|
||||
repeated ColumnFilter column_filters = 3;
|
||||
optional string text_query = 4; // Optional fallback text search
|
||||
optional string text_query = 4; // Fallback text search
|
||||
optional int32 limit = 5;
|
||||
optional string order_by = 6;
|
||||
optional bool order_desc = 7;
|
||||
|
||||
@@ -210,7 +210,7 @@ message CopyProfileResponse {
|
||||
message GetColumnAliasRenameHistoryRequest {
|
||||
string profile_name = 1;
|
||||
|
||||
// Optional filter. When omitted, returns all tables in the profile.
|
||||
// Filter. When omitted, returns all tables in the profile.
|
||||
optional int64 table_definition_id = 2;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
syntax = "proto3";
|
||||
package komp_ac.table_script;
|
||||
|
||||
// Manages column-computation scripts for user-defined tables.
|
||||
// Manages column-computation scripts for user-defined tables and supplies the
|
||||
// dependency data used by the client-side Steel runtime.
|
||||
// Each script belongs to a single table (table_definition_id) and populates
|
||||
// exactly one target column in that table. The server:
|
||||
// - Validates script syntax (non-empty, balanced parentheses, starts with '(')
|
||||
@@ -13,7 +14,16 @@ package komp_ac.table_script;
|
||||
// - Analyzes dependencies and prevents cycles across the schema
|
||||
// - Transforms the script to decimal-safe math (steel_decimal)
|
||||
// - Upserts into table_scripts and records dependencies in script_dependencies
|
||||
// The whole operation is transactional.
|
||||
// - Hydrates external column and aggregate inputs requested by the client
|
||||
//
|
||||
// The client fetches stored scripts and their declared dependencies, builds a
|
||||
// restricted Steel context, and executes scripts for immediate form feedback.
|
||||
// Current-table values come from the client's active row snapshot. External
|
||||
// values must come from HydrateScriptDependencies; the client must not query
|
||||
// arbitrary database data from inside the Steel VM.
|
||||
//
|
||||
// Server-side persistence remains authoritative and recalculates affected rows.
|
||||
// Script creation and update are transactional.
|
||||
service TableScript {
|
||||
// Create or update a script for a specific table and target column.
|
||||
//
|
||||
@@ -41,10 +51,28 @@ service TableScript {
|
||||
// - Returns the stored, transformed script from table_scripts
|
||||
// - Includes normalized dependency metadata from script_dependencies
|
||||
// - Returns an empty scripts list when the table has no scripts
|
||||
//
|
||||
// Client use:
|
||||
// - Registers each client-evaluable script with the computed-field runtime
|
||||
// - Uses dependencies as the allowlist for values exposed to the Steel VM
|
||||
// - Uses target_column_type to validate and convert the script result
|
||||
rpc GetTableScripts(GetTableScriptsRequest) returns (GetTableScriptsResponse);
|
||||
|
||||
rpc GetScriptDependencyValues(GetScriptDependencyValuesRequest)
|
||||
returns (GetScriptDependencyValuesResponse);
|
||||
// Build the external data snapshot needed to execute a table's scripts in
|
||||
// the client-side Steel runtime.
|
||||
//
|
||||
// The server derives the required inputs from stored script_dependencies;
|
||||
// callers do not choose arbitrary tables or columns. Direct related-column
|
||||
// reads are grouped by related row, while related aggregates are evaluated
|
||||
// through the analytics runtime. Returned values include logical type and
|
||||
// currency metadata so the client can create correctly typed ScriptValues.
|
||||
//
|
||||
// Current-table column values are intentionally not returned. The client
|
||||
// supplies those directly from row_data so unsaved edits participate in
|
||||
// immediate calculations. The response replaces the client's previous
|
||||
// script dependency cache as one complete hydration snapshot.
|
||||
rpc HydrateScriptDependencies(HydrateScriptDependenciesRequest)
|
||||
returns (HydrateScriptDependenciesResponse);
|
||||
}
|
||||
|
||||
// Request to create or update a script bound to a specific table and column.
|
||||
@@ -77,8 +105,10 @@ message PostTableScriptRequest {
|
||||
// @sum(table.column), @min(table.column), @max(table.column),
|
||||
// @count(table.column), @count_distinct(table.column),
|
||||
// @any(table.boolean), @all(table.boolean),
|
||||
// @count_rows(table), @exists(table)
|
||||
// The related table must be a direct child or share exactly one parent.
|
||||
// @count_rows(table via anchor), @exists(table via anchor)
|
||||
// Every related aggregate requires the `via anchor` clause. The related
|
||||
// table must be reachable through that anchor by an unambiguous FK path;
|
||||
// the path may span multiple FK hops.
|
||||
// - Raw SQL access is not supported; steel_query_sql is rejected
|
||||
//
|
||||
// Math operations:
|
||||
@@ -120,45 +150,97 @@ message GetTableScriptsRequest {
|
||||
}
|
||||
|
||||
message GetTableScriptsResponse {
|
||||
// Scripts and dependency allowlists used to configure the client Steel runtime.
|
||||
repeated StoredTableScript scripts = 1;
|
||||
}
|
||||
|
||||
message StoredTableScript {
|
||||
// Persistent script identifier.
|
||||
int64 id = 1;
|
||||
// Display-name key of the current-table field populated by this script.
|
||||
string target_column = 2;
|
||||
// Logical type used by the client to validate and convert the result.
|
||||
string target_column_type = 3;
|
||||
// Validated and transformed Steel expression executed by the client for
|
||||
// immediate feedback and by the server for authoritative persistence.
|
||||
string script = 4;
|
||||
string description = 5;
|
||||
// Complete allowlist of data inputs that may be exposed to this script.
|
||||
repeated ScriptDependency dependencies = 6;
|
||||
// Whether changes to dependency rows trigger authoritative server propagation.
|
||||
bool recompute_on_dependency_change = 7;
|
||||
}
|
||||
|
||||
message ScriptDependency {
|
||||
// Logical table name referenced by the script.
|
||||
string target_table = 1;
|
||||
// Normalized dependency kind, such as column_access or related_aggregate.
|
||||
string dependency_type = 2;
|
||||
// Logical column name. Empty for aggregates that operate on rows only.
|
||||
string column = 3;
|
||||
// Deprecated legacy field. Raw SQL dependencies are no longer produced.
|
||||
string query_fragment = 4;
|
||||
// Aggregate operation name, such as sum, count_rows, or exists; empty for
|
||||
// column_access dependencies.
|
||||
string operation = 5;
|
||||
// Relationship table used to match the owner row to the related collection.
|
||||
string via_table = 6;
|
||||
}
|
||||
|
||||
message GetScriptDependencyValuesRequest {
|
||||
// Identifies the active form row whose external Steel inputs must be hydrated.
|
||||
message HydrateScriptDependenciesRequest {
|
||||
// Required profile/database schema containing the scripted table.
|
||||
string profile_name = 1;
|
||||
// Required logical name of the table owning the scripts.
|
||||
string table_name = 2;
|
||||
// Persisted owner-row ID, or zero for a new unsaved row.
|
||||
int64 row_id = 3;
|
||||
// Complete current client form snapshot keyed by logical column name.
|
||||
// It contains unsaved current-table values and related foreign keys such as
|
||||
// "customer_id". The server uses it to resolve related rows and new-row
|
||||
// aggregate semantics; it is not an arbitrary dependency request.
|
||||
map<string, string> row_data = 4;
|
||||
}
|
||||
|
||||
message ScriptDependencyValue {
|
||||
string operation = 1;
|
||||
string target_table = 2;
|
||||
// One declared cross-table column input for the client Steel context.
|
||||
message HydratedColumnValue {
|
||||
// Logical related-table name used by steel_get_column.
|
||||
string target_table = 1;
|
||||
// Related row from which the value was loaded.
|
||||
int64 row_id = 2;
|
||||
// Logical column name used by steel_get_column.
|
||||
string column = 3;
|
||||
string via_table = 4;
|
||||
string value = 5;
|
||||
// String-encoded database value. An empty string represents NULL/empty input.
|
||||
string value = 4;
|
||||
// Logical database type used to create a typed client ScriptValue.
|
||||
string field_type = 5;
|
||||
// Related table's base currency for MONEY values; otherwise empty.
|
||||
string base_currency = 6;
|
||||
}
|
||||
|
||||
message GetScriptDependencyValuesResponse {
|
||||
repeated ScriptDependencyValue values = 1;
|
||||
// One declared related-collection aggregate input for the client Steel context.
|
||||
message HydratedAggregateValue {
|
||||
// Normalized aggregate operation: sum, min, max, count, count_distinct,
|
||||
// any, all, count_rows, or exists.
|
||||
string operation = 1;
|
||||
// Logical table whose related rows were aggregated.
|
||||
string target_table = 2;
|
||||
// Logical aggregated column; empty for count_rows and exists.
|
||||
string column = 3;
|
||||
// Relationship anchor used to distinguish aggregate dependency paths.
|
||||
string via_table = 4;
|
||||
// String-encoded aggregate result.
|
||||
string value = 5;
|
||||
// Logical source-column type; empty for row-only aggregates.
|
||||
string field_type = 6;
|
||||
// Aggregate table's base currency for MONEY values; otherwise empty.
|
||||
string base_currency = 7;
|
||||
}
|
||||
|
||||
// Complete external dependency snapshot for client-side Steel execution.
|
||||
message HydrateScriptDependenciesResponse {
|
||||
// Exact related-column inputs declared by stored scripts.
|
||||
repeated HydratedColumnValue columns = 1;
|
||||
// Exact related aggregate inputs declared by stored scripts.
|
||||
repeated HydratedAggregateValue aggregates = 2;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -55,7 +55,7 @@ pub struct ExecuteAnalyticsQueryRequest {
|
||||
/// Exactly one read-only SELECT query. Table and column names are public aliases.
|
||||
#[prost(string, tag = "2")]
|
||||
pub sql: ::prost::alloc::string::String,
|
||||
/// Optional result cap. Zero uses the server default; the server maximum still applies.
|
||||
/// Result cap. Zero uses the server default; the server maximum still applies.
|
||||
#[prost(uint32, tag = "3")]
|
||||
pub max_rows: u32,
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ pub struct Search2Request {
|
||||
pub table_name: ::prost::alloc::string::String,
|
||||
#[prost(message, repeated, tag = "3")]
|
||||
pub column_filters: ::prost::alloc::vec::Vec<ColumnFilter>,
|
||||
/// Optional fallback text search
|
||||
/// Fallback text search
|
||||
#[prost(string, optional, tag = "4")]
|
||||
pub text_query: ::core::option::Option<::prost::alloc::string::String>,
|
||||
#[prost(int32, optional, tag = "5")]
|
||||
|
||||
@@ -193,7 +193,7 @@ pub struct CopyProfileResponse {
|
||||
pub struct GetColumnAliasRenameHistoryRequest {
|
||||
#[prost(string, tag = "1")]
|
||||
pub profile_name: ::prost::alloc::string::String,
|
||||
/// Optional filter. When omitted, returns all tables in the profile.
|
||||
/// Filter. When omitted, returns all tables in the profile.
|
||||
#[prost(int64, optional, tag = "2")]
|
||||
pub table_definition_id: ::core::option::Option<i64>,
|
||||
}
|
||||
|
||||
@@ -33,8 +33,10 @@ pub struct PostTableScriptRequest {
|
||||
/// @sum(table.column), @min(table.column), @max(table.column),
|
||||
/// @count(table.column), @count_distinct(table.column),
|
||||
/// @any(table.boolean), @all(table.boolean),
|
||||
/// @count_rows(table), @exists(table)
|
||||
/// The related table must be a direct child or share exactly one parent.
|
||||
/// @count_rows(table via anchor), @exists(table via anchor)
|
||||
/// Every related aggregate requires the `via anchor` clause. The related
|
||||
/// table must be reachable through that anchor by an unambiguous FK path;
|
||||
/// the path may span multiple FK hops.
|
||||
/// * Raw SQL access is not supported; steel_query_sql is rejected
|
||||
///
|
||||
/// Math operations:
|
||||
@@ -82,74 +84,135 @@ pub struct GetTableScriptsRequest {
|
||||
}
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct GetTableScriptsResponse {
|
||||
/// Scripts and dependency allowlists used to configure the client Steel runtime.
|
||||
#[prost(message, repeated, tag = "1")]
|
||||
pub scripts: ::prost::alloc::vec::Vec<StoredTableScript>,
|
||||
}
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct StoredTableScript {
|
||||
/// Persistent script identifier.
|
||||
#[prost(int64, tag = "1")]
|
||||
pub id: i64,
|
||||
/// Display-name key of the current-table field populated by this script.
|
||||
#[prost(string, tag = "2")]
|
||||
pub target_column: ::prost::alloc::string::String,
|
||||
/// Logical type used by the client to validate and convert the result.
|
||||
#[prost(string, tag = "3")]
|
||||
pub target_column_type: ::prost::alloc::string::String,
|
||||
/// Validated and transformed Steel expression executed by the client for
|
||||
/// immediate feedback and by the server for authoritative persistence.
|
||||
#[prost(string, tag = "4")]
|
||||
pub script: ::prost::alloc::string::String,
|
||||
#[prost(string, tag = "5")]
|
||||
pub description: ::prost::alloc::string::String,
|
||||
/// Complete allowlist of data inputs that may be exposed to this script.
|
||||
#[prost(message, repeated, tag = "6")]
|
||||
pub dependencies: ::prost::alloc::vec::Vec<ScriptDependency>,
|
||||
/// Whether changes to dependency rows trigger authoritative server propagation.
|
||||
#[prost(bool, tag = "7")]
|
||||
pub recompute_on_dependency_change: bool,
|
||||
}
|
||||
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
|
||||
pub struct ScriptDependency {
|
||||
/// Logical table name referenced by the script.
|
||||
#[prost(string, tag = "1")]
|
||||
pub target_table: ::prost::alloc::string::String,
|
||||
/// Normalized dependency kind, such as column_access or related_aggregate.
|
||||
#[prost(string, tag = "2")]
|
||||
pub dependency_type: ::prost::alloc::string::String,
|
||||
/// Logical column name. Empty for aggregates that operate on rows only.
|
||||
#[prost(string, tag = "3")]
|
||||
pub column: ::prost::alloc::string::String,
|
||||
/// Deprecated legacy field. Raw SQL dependencies are no longer produced.
|
||||
#[prost(string, tag = "4")]
|
||||
pub query_fragment: ::prost::alloc::string::String,
|
||||
/// Aggregate operation name, such as sum, count_rows, or exists; empty for
|
||||
/// column_access dependencies.
|
||||
#[prost(string, tag = "5")]
|
||||
pub operation: ::prost::alloc::string::String,
|
||||
/// Relationship table used to match the owner row to the related collection.
|
||||
#[prost(string, tag = "6")]
|
||||
pub via_table: ::prost::alloc::string::String,
|
||||
}
|
||||
/// Identifies the active form row whose external Steel inputs must be hydrated.
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct GetScriptDependencyValuesRequest {
|
||||
pub struct HydrateScriptDependenciesRequest {
|
||||
/// Required profile/database schema containing the scripted table.
|
||||
#[prost(string, tag = "1")]
|
||||
pub profile_name: ::prost::alloc::string::String,
|
||||
/// Required logical name of the table owning the scripts.
|
||||
#[prost(string, tag = "2")]
|
||||
pub table_name: ::prost::alloc::string::String,
|
||||
/// Persisted owner-row ID, or zero for a new unsaved row.
|
||||
#[prost(int64, tag = "3")]
|
||||
pub row_id: i64,
|
||||
/// Complete current client form snapshot keyed by logical column name.
|
||||
/// It contains unsaved current-table values and related foreign keys such as
|
||||
/// "customer_id". The server uses it to resolve related rows and new-row
|
||||
/// aggregate semantics; it is not an arbitrary dependency request.
|
||||
#[prost(map = "string, string", tag = "4")]
|
||||
pub row_data: ::std::collections::HashMap<
|
||||
::prost::alloc::string::String,
|
||||
::prost::alloc::string::String,
|
||||
>,
|
||||
}
|
||||
/// One declared cross-table column input for the client Steel context.
|
||||
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
|
||||
pub struct ScriptDependencyValue {
|
||||
pub struct HydratedColumnValue {
|
||||
/// Logical related-table name used by steel_get_column.
|
||||
#[prost(string, tag = "1")]
|
||||
pub operation: ::prost::alloc::string::String,
|
||||
#[prost(string, tag = "2")]
|
||||
pub target_table: ::prost::alloc::string::String,
|
||||
/// Related row from which the value was loaded.
|
||||
#[prost(int64, tag = "2")]
|
||||
pub row_id: i64,
|
||||
/// Logical column name used by steel_get_column.
|
||||
#[prost(string, tag = "3")]
|
||||
pub column: ::prost::alloc::string::String,
|
||||
/// String-encoded database value. An empty string represents NULL/empty input.
|
||||
#[prost(string, tag = "4")]
|
||||
pub value: ::prost::alloc::string::String,
|
||||
/// Logical database type used to create a typed client ScriptValue.
|
||||
#[prost(string, tag = "5")]
|
||||
pub field_type: ::prost::alloc::string::String,
|
||||
/// Related table's base currency for MONEY values; otherwise empty.
|
||||
#[prost(string, tag = "6")]
|
||||
pub base_currency: ::prost::alloc::string::String,
|
||||
}
|
||||
/// One declared related-collection aggregate input for the client Steel context.
|
||||
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
|
||||
pub struct HydratedAggregateValue {
|
||||
/// Normalized aggregate operation: sum, min, max, count, count_distinct,
|
||||
/// any, all, count_rows, or exists.
|
||||
#[prost(string, tag = "1")]
|
||||
pub operation: ::prost::alloc::string::String,
|
||||
/// Logical table whose related rows were aggregated.
|
||||
#[prost(string, tag = "2")]
|
||||
pub target_table: ::prost::alloc::string::String,
|
||||
/// Logical aggregated column; empty for count_rows and exists.
|
||||
#[prost(string, tag = "3")]
|
||||
pub column: ::prost::alloc::string::String,
|
||||
/// Relationship anchor used to distinguish aggregate dependency paths.
|
||||
#[prost(string, tag = "4")]
|
||||
pub via_table: ::prost::alloc::string::String,
|
||||
/// String-encoded aggregate result.
|
||||
#[prost(string, tag = "5")]
|
||||
pub value: ::prost::alloc::string::String,
|
||||
/// Logical source-column type; empty for row-only aggregates.
|
||||
#[prost(string, tag = "6")]
|
||||
pub field_type: ::prost::alloc::string::String,
|
||||
/// Aggregate table's base currency for MONEY values; otherwise empty.
|
||||
#[prost(string, tag = "7")]
|
||||
pub base_currency: ::prost::alloc::string::String,
|
||||
}
|
||||
/// Complete external dependency snapshot for client-side Steel execution.
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct GetScriptDependencyValuesResponse {
|
||||
pub struct HydrateScriptDependenciesResponse {
|
||||
/// Exact related-column inputs declared by stored scripts.
|
||||
#[prost(message, repeated, tag = "1")]
|
||||
pub values: ::prost::alloc::vec::Vec<ScriptDependencyValue>,
|
||||
pub columns: ::prost::alloc::vec::Vec<HydratedColumnValue>,
|
||||
/// Exact related aggregate inputs declared by stored scripts.
|
||||
#[prost(message, repeated, tag = "2")]
|
||||
pub aggregates: ::prost::alloc::vec::Vec<HydratedAggregateValue>,
|
||||
}
|
||||
/// Generated client implementations.
|
||||
pub mod table_script_client {
|
||||
@@ -162,7 +225,8 @@ pub mod table_script_client {
|
||||
)]
|
||||
use tonic::codegen::*;
|
||||
use tonic::codegen::http::Uri;
|
||||
/// Manages column-computation scripts for user-defined tables.
|
||||
/// Manages column-computation scripts for user-defined tables and supplies the
|
||||
/// dependency data used by the client-side Steel runtime.
|
||||
/// Each script belongs to a single table (table_definition_id) and populates
|
||||
/// exactly one target column in that table. The server:
|
||||
///
|
||||
@@ -174,7 +238,16 @@ pub mod table_script_client {
|
||||
/// * Analyzes dependencies and prevents cycles across the schema
|
||||
/// * Transforms the script to decimal-safe math (steel_decimal)
|
||||
/// * Upserts into table_scripts and records dependencies in script_dependencies
|
||||
/// The whole operation is transactional.
|
||||
/// * Hydrates external column and aggregate inputs requested by the client
|
||||
///
|
||||
/// The client fetches stored scripts and their declared dependencies, builds a
|
||||
/// restricted Steel context, and executes scripts for immediate form feedback.
|
||||
/// Current-table values come from the client's active row snapshot. External
|
||||
/// values must come from HydrateScriptDependencies; the client must not query
|
||||
/// arbitrary database data from inside the Steel VM.
|
||||
///
|
||||
/// Server-side persistence remains authoritative and recalculates affected rows.
|
||||
/// Script creation and update are transactional.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TableScriptClient<T> {
|
||||
inner: tonic::client::Grpc<T>,
|
||||
@@ -310,6 +383,12 @@ pub mod table_script_client {
|
||||
/// * Returns the stored, transformed script from table_scripts
|
||||
/// * Includes normalized dependency metadata from script_dependencies
|
||||
/// * Returns an empty scripts list when the table has no scripts
|
||||
///
|
||||
/// Client use:
|
||||
///
|
||||
/// * Registers each client-evaluable script with the computed-field runtime
|
||||
/// * Uses dependencies as the allowlist for values exposed to the Steel VM
|
||||
/// * Uses target_column_type to validate and convert the script result
|
||||
pub async fn get_table_scripts(
|
||||
&mut self,
|
||||
request: impl tonic::IntoRequest<super::GetTableScriptsRequest>,
|
||||
@@ -339,11 +418,24 @@ pub mod table_script_client {
|
||||
);
|
||||
self.inner.unary(req, path, codec).await
|
||||
}
|
||||
pub async fn get_script_dependency_values(
|
||||
/// Build the external data snapshot needed to execute a table's scripts in
|
||||
/// the client-side Steel runtime.
|
||||
///
|
||||
/// The server derives the required inputs from stored script_dependencies;
|
||||
/// callers do not choose arbitrary tables or columns. Direct related-column
|
||||
/// reads are grouped by related row, while related aggregates are evaluated
|
||||
/// through the analytics runtime. Returned values include logical type and
|
||||
/// currency metadata so the client can create correctly typed ScriptValues.
|
||||
///
|
||||
/// Current-table column values are intentionally not returned. The client
|
||||
/// supplies those directly from row_data so unsaved edits participate in
|
||||
/// immediate calculations. The response replaces the client's previous
|
||||
/// script dependency cache as one complete hydration snapshot.
|
||||
pub async fn hydrate_script_dependencies(
|
||||
&mut self,
|
||||
request: impl tonic::IntoRequest<super::GetScriptDependencyValuesRequest>,
|
||||
request: impl tonic::IntoRequest<super::HydrateScriptDependenciesRequest>,
|
||||
) -> std::result::Result<
|
||||
tonic::Response<super::GetScriptDependencyValuesResponse>,
|
||||
tonic::Response<super::HydrateScriptDependenciesResponse>,
|
||||
tonic::Status,
|
||||
> {
|
||||
self.inner
|
||||
@@ -356,14 +448,14 @@ pub mod table_script_client {
|
||||
})?;
|
||||
let codec = tonic_prost::ProstCodec::default();
|
||||
let path = http::uri::PathAndQuery::from_static(
|
||||
"/komp_ac.table_script.TableScript/GetScriptDependencyValues",
|
||||
"/komp_ac.table_script.TableScript/HydrateScriptDependencies",
|
||||
);
|
||||
let mut req = request.into_request();
|
||||
req.extensions_mut()
|
||||
.insert(
|
||||
GrpcMethod::new(
|
||||
"komp_ac.table_script.TableScript",
|
||||
"GetScriptDependencyValues",
|
||||
"HydrateScriptDependencies",
|
||||
),
|
||||
);
|
||||
self.inner.unary(req, path, codec).await
|
||||
@@ -416,6 +508,12 @@ pub mod table_script_server {
|
||||
/// * Returns the stored, transformed script from table_scripts
|
||||
/// * Includes normalized dependency metadata from script_dependencies
|
||||
/// * Returns an empty scripts list when the table has no scripts
|
||||
///
|
||||
/// Client use:
|
||||
///
|
||||
/// * Registers each client-evaluable script with the computed-field runtime
|
||||
/// * Uses dependencies as the allowlist for values exposed to the Steel VM
|
||||
/// * Uses target_column_type to validate and convert the script result
|
||||
async fn get_table_scripts(
|
||||
&self,
|
||||
request: tonic::Request<super::GetTableScriptsRequest>,
|
||||
@@ -423,15 +521,29 @@ pub mod table_script_server {
|
||||
tonic::Response<super::GetTableScriptsResponse>,
|
||||
tonic::Status,
|
||||
>;
|
||||
async fn get_script_dependency_values(
|
||||
/// Build the external data snapshot needed to execute a table's scripts in
|
||||
/// the client-side Steel runtime.
|
||||
///
|
||||
/// The server derives the required inputs from stored script_dependencies;
|
||||
/// callers do not choose arbitrary tables or columns. Direct related-column
|
||||
/// reads are grouped by related row, while related aggregates are evaluated
|
||||
/// through the analytics runtime. Returned values include logical type and
|
||||
/// currency metadata so the client can create correctly typed ScriptValues.
|
||||
///
|
||||
/// Current-table column values are intentionally not returned. The client
|
||||
/// supplies those directly from row_data so unsaved edits participate in
|
||||
/// immediate calculations. The response replaces the client's previous
|
||||
/// script dependency cache as one complete hydration snapshot.
|
||||
async fn hydrate_script_dependencies(
|
||||
&self,
|
||||
request: tonic::Request<super::GetScriptDependencyValuesRequest>,
|
||||
request: tonic::Request<super::HydrateScriptDependenciesRequest>,
|
||||
) -> std::result::Result<
|
||||
tonic::Response<super::GetScriptDependencyValuesResponse>,
|
||||
tonic::Response<super::HydrateScriptDependenciesResponse>,
|
||||
tonic::Status,
|
||||
>;
|
||||
}
|
||||
/// Manages column-computation scripts for user-defined tables.
|
||||
/// Manages column-computation scripts for user-defined tables and supplies the
|
||||
/// dependency data used by the client-side Steel runtime.
|
||||
/// Each script belongs to a single table (table_definition_id) and populates
|
||||
/// exactly one target column in that table. The server:
|
||||
///
|
||||
@@ -443,7 +555,16 @@ pub mod table_script_server {
|
||||
/// * Analyzes dependencies and prevents cycles across the schema
|
||||
/// * Transforms the script to decimal-safe math (steel_decimal)
|
||||
/// * Upserts into table_scripts and records dependencies in script_dependencies
|
||||
/// The whole operation is transactional.
|
||||
/// * Hydrates external column and aggregate inputs requested by the client
|
||||
///
|
||||
/// The client fetches stored scripts and their declared dependencies, builds a
|
||||
/// restricted Steel context, and executes scripts for immediate form feedback.
|
||||
/// Current-table values come from the client's active row snapshot. External
|
||||
/// values must come from HydrateScriptDependencies; the client must not query
|
||||
/// arbitrary database data from inside the Steel VM.
|
||||
///
|
||||
/// Server-side persistence remains authoritative and recalculates affected rows.
|
||||
/// Script creation and update are transactional.
|
||||
#[derive(Debug)]
|
||||
pub struct TableScriptServer<T> {
|
||||
inner: Arc<T>,
|
||||
@@ -610,15 +731,15 @@ pub mod table_script_server {
|
||||
};
|
||||
Box::pin(fut)
|
||||
}
|
||||
"/komp_ac.table_script.TableScript/GetScriptDependencyValues" => {
|
||||
"/komp_ac.table_script.TableScript/HydrateScriptDependencies" => {
|
||||
#[allow(non_camel_case_types)]
|
||||
struct GetScriptDependencyValuesSvc<T: TableScript>(pub Arc<T>);
|
||||
struct HydrateScriptDependenciesSvc<T: TableScript>(pub Arc<T>);
|
||||
impl<
|
||||
T: TableScript,
|
||||
> tonic::server::UnaryService<
|
||||
super::GetScriptDependencyValuesRequest,
|
||||
> for GetScriptDependencyValuesSvc<T> {
|
||||
type Response = super::GetScriptDependencyValuesResponse;
|
||||
super::HydrateScriptDependenciesRequest,
|
||||
> for HydrateScriptDependenciesSvc<T> {
|
||||
type Response = super::HydrateScriptDependenciesResponse;
|
||||
type Future = BoxFuture<
|
||||
tonic::Response<Self::Response>,
|
||||
tonic::Status,
|
||||
@@ -626,12 +747,12 @@ pub mod table_script_server {
|
||||
fn call(
|
||||
&mut self,
|
||||
request: tonic::Request<
|
||||
super::GetScriptDependencyValuesRequest,
|
||||
super::HydrateScriptDependenciesRequest,
|
||||
>,
|
||||
) -> Self::Future {
|
||||
let inner = Arc::clone(&self.0);
|
||||
let fut = async move {
|
||||
<T as TableScript>::get_script_dependency_values(
|
||||
<T as TableScript>::hydrate_script_dependencies(
|
||||
&inner,
|
||||
request,
|
||||
)
|
||||
@@ -646,7 +767,7 @@ pub mod table_script_server {
|
||||
let max_encoding_message_size = self.max_encoding_message_size;
|
||||
let inner = self.inner.clone();
|
||||
let fut = async move {
|
||||
let method = GetScriptDependencyValuesSvc(inner);
|
||||
let method = HydrateScriptDependenciesSvc(inner);
|
||||
let codec = tonic_prost::ProstCodec::default();
|
||||
let mut grpc = tonic::server::Grpc::new(codec)
|
||||
.apply_compression_config(
|
||||
|
||||
Reference in New Issue
Block a user