diff --git a/crates/erp-plugin/src/manifest.rs b/crates/erp-plugin/src/manifest.rs index a5986f9..df08b4c 100644 --- a/crates/erp-plugin/src/manifest.rs +++ b/crates/erp-plugin/src/manifest.rs @@ -83,6 +83,56 @@ pub enum PluginFieldType { Decimal, } +impl PluginFieldType { + /// Generated Column 的 SQL 类型 + pub fn generated_sql_type(&self) -> &'static str { + match self { + Self::String | Self::Json => "TEXT", + Self::Integer => "INTEGER", + Self::Float => "DOUBLE PRECISION", + Self::Decimal => "NUMERIC", + Self::Boolean => "BOOLEAN", + Self::Date => "DATE", + Self::DateTime => "TIMESTAMPTZ", + Self::Uuid => "UUID", + } + } + + /// Generated Column 的表达式 + pub fn generated_expr(&self, field_name: &str) -> String { + match self { + Self::String | Self::Json => format!("data->>'{}'", field_name), + _ => format!("(data->>'{}')::{}", field_name, self.generated_sql_type()), + } + } + + /// 该类型是否适合生成 Generated Column + pub fn supports_generated_column(&self) -> bool { + !matches!(self, Self::Json) + } +} + +impl PluginField { + /// 测试辅助:构造一个全默认值的 PluginField + #[cfg(test)] + pub fn default_for_field() -> Self { + Self { + name: String::new(), + field_type: PluginFieldType::String, + required: false, + unique: false, + default: None, + display_name: None, + ui_widget: None, + options: None, + searchable: None, + filterable: None, + sortable: None, + visible_when: None, + } + } +} + /// 索引定义 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct PluginIndex { @@ -529,4 +579,24 @@ label = "空标签页" let result = parse_manifest(toml); assert!(result.is_err()); } + + #[test] + fn field_type_to_sql_mapping() { + assert_eq!(PluginFieldType::String.generated_sql_type(), "TEXT"); + assert_eq!(PluginFieldType::Integer.generated_sql_type(), "INTEGER"); + assert_eq!(PluginFieldType::Float.generated_sql_type(), "DOUBLE PRECISION"); + assert_eq!(PluginFieldType::Decimal.generated_sql_type(), "NUMERIC"); + assert_eq!(PluginFieldType::Boolean.generated_sql_type(), "BOOLEAN"); + assert_eq!(PluginFieldType::Date.generated_sql_type(), "DATE"); + assert_eq!(PluginFieldType::DateTime.generated_sql_type(), "TIMESTAMPTZ"); + assert_eq!(PluginFieldType::Uuid.generated_sql_type(), "UUID"); + assert_eq!(PluginFieldType::Json.generated_sql_type(), "TEXT"); + } + + #[test] + fn field_type_generated_expression() { + assert_eq!(PluginFieldType::String.generated_expr("name"), "data->>'name'"); + assert_eq!(PluginFieldType::Integer.generated_expr("age"), "(data->>'age')::INTEGER"); + assert_eq!(PluginFieldType::Uuid.generated_expr("ref_id"), "(data->>'ref_id')::UUID"); + } }