Sign in

    jeeflow-persist

    jeeflow dynamic table persist (DynamicTableWriter + PersistPostInterceptor + Meta)

    Download zip
    Author
    Version
    0.1.30
    License
    Apache-2.0
    Last updated
    15 days ago
    Downloads
    341

    #jeeflow-persist

    Workflow → business-table persistence for jeeflow — ARCHIVE / SYNC with field permissions.

    mooncakes License

    PersistPostInterceptor copies form data out of running workflow instances into your own business tables, driven entirely by the process definition — the role jeeflow-persist plays for the MoonBit build of jeeflow-moon.

    #Quickstart

    let provider = @persist.InMemoryMetaProvider::new()
    let meta = @persist.TableMeta::make("expense", "报销")
    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)

    Process definition drives everything:

    {"persistMode": "ARCHIVE", "relTableName": "expense"}

    • ARCHIVE — at the end node, on FINISHED + agree (submitType=1), insert the full f_* form once; idempotent by the process_instance_id key.
    • SYNC — insert at start → update at each task (business fields filtered by the target node's field.PERMISSION_*: readonly/hidden never write through) → final-state update at the end; a {nodeId}_{state} status column is probed automatically.
    • Safety — dynamic table names are validated (alnum+underscore, wf_/sys_/… prefixes refused) and failures are loud, never silent.

    #License

    Apache-2.0 — part of jeeflow-moon.

    DynamicTableWriter

    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

    }

    DynamicTableWriter trait(MoonBit:大接口 trait 形态)

    issues/149:六法全部 async —— 本栈写真库只有 moonmysql 的 async 连接这一条路,同步形状 发不出查询(145-6 记的机理)。async 由 trait 声明承载:impl … with fn 处不重复写 async(实测写了判 parse error),⇒ InMemoryTableWriter 六支 impl 与 &DynamicTableWriter 的六处调用点都不用改;唯一要跟着改的是同步函数里调 writer 的 put_state_field。 同形参照=core/spi/repository.mbt 的 ProcessRepository(async trait + repository-mysql 真库实现)。 ⚠ 列探测(columns)归属裁决=留在 writer:参考实现 java persist/DynamicTableWriter.java:20 的 filterColumns 就挂在 writer 上,而 IDynamicMetaProvider 管字段权限/显示元数据——两者在 java 本就并存,故不并入 DynamicMetaProviderFns(146 缺口二),也不留"同一件事两个端口"。

    DynamicMetaProviderFns

    pub(all) struct DynamicMetaProviderFns {
    load_table_meta : async (String) -> TableMeta? raise
    JeeflowError

    }

    IDynamicMetaProvider 的 MoonBit 同位(issues/146 缺口二)。 java 侧这个端口就定义在 jeeflow-persist/meta(不在 core),消费点是 MetaTableWriter/Reader ⇒ 本栈同位同样落在 persist:归档/SYNC 的写侧与回显读侧共用一份元数据(storageType 语义两侧一致)。 load_table_meta 是 async:集成方的元数据来源是库(mldong dev_schema / information_schema), 同步形状就会重演缺口一——启动期快照、改表结构引擎看不见。 未注入 ⇒ 引擎行为与既往一致(InMemory 档照常,缺省不启用外部元数据)。

    FieldMeta

    pub(all) struct FieldMeta {
    column_name : String
    column_type : String
    display_name : String
    nullable : Bool
    default_value : String?
    permission : Int
    }

    字段元数据(动态表列)

    FieldMeta::is_editable

    fn FieldMeta::is_editable(self : FieldMeta) -> Bool

    FieldMeta::is_visible

    fn FieldMeta::is_visible(self : FieldMeta) -> Bool

    FieldMeta::make

    fn FieldMeta::make(column_name : String, column_type : String, display_name : String) -> FieldMeta

    InMemoryMetaProvider

    pub(all) struct InMemoryMetaProvider {
    tables : Map[String, TableMeta]
    }

    IDynamicMetaProvider 内存实现

    InMemoryMetaProvider::as_provider

    内存档 → 端口(纯内存读 ⇒ 经 @spi.async_of_sync 桥,注册点零警告)

    InMemoryMetaProvider::get_table_meta

    fn InMemoryMetaProvider::get_table_meta(self : InMemoryMetaProvider, table_name : String) -> TableMeta?

    InMemoryMetaProvider::list_table_names

    fn InMemoryMetaProvider::list_table_names(self : InMemoryMetaProvider) -> Array[String]

    InMemoryMetaProvider::new

    InMemoryMetaProvider::register

    fn InMemoryMetaProvider::register(self : InMemoryMetaProvider, meta : TableMeta) -> Unit

    InMemoryTableWriter

    pub(all) struct InMemoryTableWriter {
    id_counter : Int64
    tables : Map[String, Map[Int64, Map[String, Json]]]
    }

    InMemoryTableWriter::columns

    async fn InMemoryTableWriter::columns(self : InMemoryTableWriter, _table_name : String, candidates : Array[String]) -> Array[String] raise
    JeeflowError

    InMemoryTableWriter::exists

    async fn InMemoryTableWriter::exists(self : InMemoryTableWriter, table_name : String, id : Int64) -> Bool raise
    JeeflowError

    InMemoryTableWriter::exists_by_key

    async fn InMemoryTableWriter::exists_by_key(self : InMemoryTableWriter, table_name : String, key : String, value : Int64) -> Bool raise
    JeeflowError

    InMemoryTableWriter::get_row

    fn InMemoryTableWriter::get_row(self : InMemoryTableWriter, table_name : String, id : Int64) -> Map[String, Json]?

    InMemoryTableWriter::get_row_by_key

    fn InMemoryTableWriter::get_row_by_key(self : InMemoryTableWriter, table_name : String, key : String, value : Int64) -> Map[String, Json]?

    InMemoryTableWriter::get_table_rows

    fn InMemoryTableWriter::get_table_rows(self : InMemoryTableWriter, table_name : String) -> Array[Map[String, Json]]

    InMemoryTableWriter::insert

    async fn InMemoryTableWriter::insert(self : InMemoryTableWriter, table_name : String, data : Map[String, Json]) -> Int64 raise
    JeeflowError

    InMemoryTableWriter::new

    InMemoryTableWriter::update

    async fn InMemoryTableWriter::update(self : InMemoryTableWriter, table_name : String, id : Int64, data : Map[String, Json]) -> Unit raise
    JeeflowError

    InMemoryTableWriter::update_by_key

    async fn InMemoryTableWriter::update_by_key(self : InMemoryTableWriter, table_name : String, data : Map[String, Json], key : String, value : Int64) -> Unit raise
    JeeflowError

    PersistMode

    pub enum PersistMode {
    Archive
    Sync
    } derive(Eq,
    Debug
    )

    持久化模式

    PersistMode::equal

    fn PersistMode::equal(PersistMode, PersistMode) -> Bool
    automatically derived

    PersistMode::from_str

    fn PersistMode::from_str(s : String) -> PersistMode?

    PersistMode::not_equal

    fn PersistMode::not_equal(x : PersistMode, y : PersistMode) -> Bool

    PersistMode::to_repr

    automatically derived

    PersistPostInterceptor

    pub(all) struct PersistPostInterceptor {
    meta : DynamicMetaProviderFns
    table_writer : &DynamicTableWriter
    }

    PersistPostInterceptor::as_interceptor

    装配为引擎拦截器(order=100,后置)

    PersistPostInterceptor::make

    PersistPostInterceptor::make_from_provider

    端口档装配(issues/146 缺口二):集成方自备元数据来源(dev_schema/库内省)走这一支

    TableMeta

    pub(all) struct TableMeta {
    table_name : String
    display_name : String
    fields : Array[FieldMeta]
    }

    TableMeta::add_field

    fn TableMeta::add_field(self : TableMeta, field : FieldMeta) -> Unit

    TableMeta::get_field

    fn TableMeta::get_field(self : TableMeta, column_name : String) -> FieldMeta?

    TableMeta::make

    fn TableMeta::make(table_name : String, display_name : String) -> TableMeta

    fill_system_fields

    fn fill_system_fields(data : Map[String, Json], operator : String, is_insert : Bool) -> Unit

    系统字段填充(时间走 Clock 注入口,D-M0-3)

    is_table_name_safe

    fn is_table_name_safe(name : String) -> Bool

    动态表名安全检查:仅字母数字下划线 + 保留前缀拒绝