jeeflow dynamic table persist (DynamicTableWriter + PersistPostInterceptor + Meta)
let provider = @persist.InMemoryMetaProvider::new()
let meta = @persist.TableMeta::make("expense", "报销")
// ⚠ 元数据是**白名单**:`filter_editable` 只放行登记过且 permission=2(可编辑)的列。
// 只登记业务列 `note` 而漏掉 `process_instance_id`,归档行就带着空幂等键落库 ⇒
// 每次办结都插一行,幂等(C16)静默失效。要写的列请登记全(issues/151 普查 X7 的实话)。
meta.add_field(@persist.FieldMeta::make("process_instance_id", "BIGINT", "流程实例ID"))
meta.add_field(@persist.FieldMeta::make("apply_user_id", "VARCHAR(64)", "申请人"))
meta.add_field(@persist.FieldMeta::make("note", "VARCHAR(200)", "备注"))
provider.register(meta)
let interceptor = @persist.PersistPostInterceptor::make(provider, my_writer)
ctx.register_interceptor(interceptor.as_interceptor()) // order = 100 (post){"persistMode": "ARCHIVE", "relTableName": "expense"}pub(open) trait DynamicTableWriter {
async fn insert(Self, String, Map[String, Json]) -> Int64 raise JeeflowError
async fn update(Self, String, Int64, Map[String, Json]) -> Unit raise JeeflowError
async fn exists(Self, String, Int64) -> Bool raise JeeflowError
async fn exists_by_key(Self, String, String, Int64) -> Bool raise JeeflowError
async fn update_by_key(Self, String, Map[String, Json], String, Int64) -> Unit raise JeeflowError
async fn columns(Self, String, Array[String]) -> Array[String] raise JeeflowError
}pub(all) struct DynamicMetaProviderFns {
load_table_meta : async (String) -> TableMeta? raise JeeflowError
}pub(all) struct FieldMeta {
column_name : String
column_type : String
display_name : String
nullable : Bool
default_value : String?
permission : Int
}fn InMemoryMetaProvider::get_table_meta(self : InMemoryMetaProvider, table_name : String) -> TableMeta?impl DynamicTableWriter for InMemoryTableWriterasync fn columns(self : InMemoryTableWriter, _table_name : String, candidates : Array[String]) -> Array[String] raise JeeflowErrorasync fn exists(self : InMemoryTableWriter, table_name : String, id : Int64) -> Bool raise JeeflowErrorasync fn exists_by_key(self : InMemoryTableWriter, table_name : String, key : String, value : Int64) -> Bool raise JeeflowErrorasync fn insert(self : InMemoryTableWriter, table_name : String, data : Map[String, Json]) -> Int64 raise JeeflowErrorasync fn update(self : InMemoryTableWriter, table_name : String, id : Int64, data : Map[String, Json]) -> Unit raise JeeflowErrorasync fn update_by_key(self : InMemoryTableWriter, table_name : String, data : Map[String, Json], key : String, value : Int64) -> Unit raise JeeflowErrorasync fn InMemoryTableWriter::columns(self : InMemoryTableWriter, _table_name : String, candidates : Array[String]) -> Array[String] raise JeeflowErrorasync fn InMemoryTableWriter::exists(self : InMemoryTableWriter, table_name : String, id : Int64) -> Bool raise JeeflowErrorasync fn InMemoryTableWriter::exists_by_key(self : InMemoryTableWriter, table_name : String, key : String, value : Int64) -> Bool raise JeeflowErrorfn InMemoryTableWriter::get_row(self : InMemoryTableWriter, table_name : String, id : Int64) -> Map[String, Json]?fn InMemoryTableWriter::get_row_by_key(self : InMemoryTableWriter, table_name : String, key : String, value : Int64) -> Map[String, Json]?fn InMemoryTableWriter::get_table_rows(self : InMemoryTableWriter, table_name : String) -> Array[Map[String, Json]]async fn InMemoryTableWriter::insert(self : InMemoryTableWriter, table_name : String, data : Map[String, Json]) -> Int64 raise JeeflowErrorasync fn InMemoryTableWriter::update(self : InMemoryTableWriter, table_name : String, id : Int64, data : Map[String, Json]) -> Unit raise JeeflowErrorasync fn InMemoryTableWriter::update_by_key(self : InMemoryTableWriter, table_name : String, data : Map[String, Json], key : String, value : Int64) -> Unit raise JeeflowErrorpub(all) struct PersistPostInterceptor {
meta : DynamicMetaProviderFns
table_writer : &DynamicTableWriter
system_fields : SystemFields
strict_columns : Bool
}async fn PersistPostInterceptor::intercept(self : PersistPostInterceptor, exec : Execution) -> Unit raise JeeflowErrorfn PersistPostInterceptor::make(meta_provider : InMemoryMetaProvider, table_writer : &DynamicTableWriter) -> PersistPostInterceptorfn PersistPostInterceptor::make_from_provider(meta : DynamicMetaProviderFns, table_writer : &DynamicTableWriter) -> PersistPostInterceptorfn PersistPostInterceptor::with_strict_columns(self : PersistPostInterceptor, strict_columns : Bool) -> PersistPostInterceptorfn PersistPostInterceptor::with_system_fields(self : PersistPostInterceptor, system_fields : SystemFields) -> PersistPostInterceptorpub(all) struct SystemFields {
create_time_col : String?
create_user_col : String?
update_time_col : String?
update_user_col : String?
is_deleted_col : String?
default_user_value : String
}fn column_names_equal(a : String, b : String, strict? : Bool) -> Boolfn fill_system_fields_with(cfg : SystemFields, data : Map[String, Json], operator : String, is_insert : Bool) -> Unitfn normalize_column(name : String) -> StringInstall
Download zipjeeflow dynamic table persist (DynamicTableWriter + PersistPostInterceptor + Meta)