feat(plugin): PluginRelation 级联删除声明 + OnDeleteStrategy
新增 OnDeleteStrategy 枚举(Nullify/Cascade/Restrict)和 PluginRelation 结构体声明实体关联关系。PluginEntity 增加 relations 字段(serde(default) 向后兼容)。
This commit is contained in:
@@ -956,6 +956,7 @@ mod tests {
|
||||
},
|
||||
],
|
||||
indexes: vec![],
|
||||
relations: vec![],
|
||||
};
|
||||
|
||||
let sql = DynamicTableManager::build_create_table_sql("erp_crm", &entity);
|
||||
@@ -996,6 +997,7 @@ mod tests {
|
||||
..PluginField::default_for_field()
|
||||
}],
|
||||
indexes: vec![],
|
||||
relations: vec![],
|
||||
};
|
||||
|
||||
let sql = DynamicTableManager::build_create_table_sql("erp_crm", &entity);
|
||||
|
||||
@@ -43,6 +43,8 @@ pub struct PluginEntity {
|
||||
pub fields: Vec<PluginField>,
|
||||
#[serde(default)]
|
||||
pub indexes: Vec<PluginIndex>,
|
||||
#[serde(default)]
|
||||
pub relations: Vec<PluginRelation>,
|
||||
}
|
||||
|
||||
/// 字段校验规则
|
||||
@@ -156,6 +158,23 @@ pub struct PluginIndex {
|
||||
pub unique: bool,
|
||||
}
|
||||
|
||||
/// 级联删除策略
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum OnDeleteStrategy {
|
||||
Nullify, // 置空外键字段
|
||||
Cascade, // 级联软删除
|
||||
Restrict, // 存在关联时拒绝删除
|
||||
}
|
||||
|
||||
/// 实体关联关系声明
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct PluginRelation {
|
||||
pub entity: String,
|
||||
pub foreign_key: String,
|
||||
pub on_delete: OnDeleteStrategy,
|
||||
}
|
||||
|
||||
/// 事件订阅配置
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct PluginEvents {
|
||||
@@ -690,4 +709,41 @@ no_cycle = true
|
||||
assert_eq!(field.no_cycle, Some(true));
|
||||
assert_eq!(field.ref_entity.as_deref(), Some("customer"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_entity_with_relations() {
|
||||
let toml = r#"
|
||||
[metadata]
|
||||
id = "test"
|
||||
name = "Test"
|
||||
version = "0.1.0"
|
||||
|
||||
[schema]
|
||||
[[schema.entities]]
|
||||
name = "customer"
|
||||
display_name = "客户"
|
||||
|
||||
[[schema.entities.fields]]
|
||||
name = "code"
|
||||
field_type = "string"
|
||||
required = true
|
||||
display_name = "编码"
|
||||
|
||||
[[schema.entities.relations]]
|
||||
entity = "contact"
|
||||
foreign_key = "customer_id"
|
||||
on_delete = "cascade"
|
||||
|
||||
[[schema.entities.relations]]
|
||||
entity = "customer_tag"
|
||||
foreign_key = "customer_id"
|
||||
on_delete = "cascade"
|
||||
"#;
|
||||
let manifest = parse_manifest(toml).unwrap();
|
||||
let entity = &manifest.schema.unwrap().entities[0];
|
||||
assert_eq!(entity.relations.len(), 2);
|
||||
assert_eq!(entity.relations[0].entity, "contact");
|
||||
assert_eq!(entity.relations[0].foreign_key, "customer_id");
|
||||
assert!(matches!(entity.relations[0].on_delete, OnDeleteStrategy::Cascade));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user