moduforge_state/
transaction.rs

1use std::ops::{Deref, DerefMut};
2use std::sync::atomic::{AtomicU64, Ordering};
3use std::sync::Arc;
4
5use async_trait::async_trait;
6use serde_json::Value;
7use tracing::{info, warn, error};
8
9use super::state::State;
10use moduforge_transform::draft::Draft;
11use moduforge_model::node::Node;
12use moduforge_model::node_pool::{NodePool};
13use moduforge_transform::attr_step::AttrStep;
14use moduforge_transform::node_step::AddNodeStep;
15use moduforge_transform::step::{Step, StepResult};
16use moduforge_transform::transform::{Transform, TransformError};
17use moduforge_transform::{ConcreteStep, PatchStep};
18use std::fmt::Debug;
19
20static IDS: AtomicU64 = AtomicU64::new(1);
21pub fn get_transaction_id() -> u64 {
22    //生成 全局自增的版本号,用于兼容性
23    IDS.fetch_add(1, Ordering::SeqCst)
24}
25
26/// 定义可执行的命令接口
27/// 要求实现 Send + Sync 以支持并发操作,并实现 Debug 以支持调试
28#[async_trait]
29pub trait Command: Send + Sync + Debug {
30    async fn execute(
31        &self,
32        tr: &mut Transaction,
33    ) -> Result<(), TransformError>;
34    fn name(&self) -> String;
35}
36
37/// 事务结构体,用于管理文档的修改操作
38#[derive(Debug, Clone)]
39pub struct Transaction {
40    /// 存储元数据的哈希表,支持任意类型数据
41    pub meta: im::HashMap<String, Arc<dyn std::any::Any>>,
42    /// 事务的时间戳
43    pub id: u64,
44    transform:Transform
45}
46unsafe impl Send for Transaction {}
47unsafe impl Sync for Transaction {}
48impl Deref for Transaction {
49    type Target = Transform;
50
51    fn deref(&self) -> &Self::Target {
52        &self.transform
53    }
54}
55
56impl DerefMut for Transaction {
57    fn deref_mut(&mut self) -> &mut Self::Target {
58        &mut self.transform
59    }
60}
61
62impl Transaction {
63    /// 执行一个事务操作
64    /// call_back: 要执行的命令
65    pub async fn transaction(
66        &mut self,
67        call_back: Arc<dyn Command>,
68    ) {
69        info!("开始执行事务: {}", call_back.name());
70        self.draft.begin = true;
71        let result = call_back.execute(self).await;
72        self.draft.begin = false;
73        match result {
74            Ok(_) => {
75                info!("事务执行成功,正在提交更改");
76                let result = self.draft.commit();
77                self.add_step(
78                    Arc::new(PatchStep { patches: result.patches.clone() }),
79                    result,
80                );
81            },
82            Err(e) => {
83                error!("事务执行失败: {}", e);
84                warn!("事务回滚");
85            },
86        }
87    }
88    /// 创建新的事务实例
89    /// state: 当前状态对象
90    /// 返回: Transaction 实例
91    pub fn new(state: &State) -> Self {
92        let node = state.doc();
93        let schema = state.schema();
94        Transaction {
95            meta: im::HashMap::new(),
96            id: get_transaction_id(),
97            transform: Transform {
98                doc: node.clone(),
99                draft: Draft::new(node),
100                steps: im::Vector::new(),
101                patches: im::Vector::new(),
102                schema,
103            },
104        }
105    }
106    /// 获取当前文档状态
107    pub fn doc(&self) -> Arc<NodePool> {
108        self.doc.clone()
109    }
110    /// 将步骤转换为具体步骤
111    pub fn as_concrete(step: &Arc<dyn Step>) -> ConcreteStep {
112        step.to_concrete()
113    }
114    /// 设置节点属性
115    /// id: 节点ID
116    /// values: 属性键值对
117    pub fn set_node_attribute(
118        &mut self,
119        id: String,
120        values: im::HashMap<String, Value>,
121    ) {
122        let _ = self.step(Arc::new(AttrStep::new(id, values)));
123    }
124    /// 添加新节点
125    /// parent_id: 父节点ID
126    /// node: 要添加的节点
127    pub fn add_node(
128        &mut self,
129        parent_id: String,
130        nodes: Vec<Node>,
131    ) {
132        let _ = self.step(Arc::new(AddNodeStep::new(parent_id, nodes)));
133    }
134    /// 设置事务时间戳
135    pub fn set_time(
136        &mut self,
137        id: u64,
138    ) -> &mut Self {
139        self.id = id;
140        self
141    }
142    /// 设置元数据
143    /// key: 键
144    /// value: 值(支持任意类型)
145    pub fn set_meta<K, T: std::any::Any>(
146        &mut self,
147        key: K,
148        value: T,
149    ) -> &mut Self
150    where
151        K: Into<String>,
152    {
153        let key_str = key.into();
154        self.meta.insert(key_str, Arc::new(value));
155        self
156    }
157    /// 获取元数据
158    /// key: 键
159    /// 返回: Option<&T>,如果存在且类型匹配则返回Some,否则返回None
160    pub fn get_meta<T: 'static, K>(
161        &self,
162        key: K,
163    ) -> Option<&T>
164    where
165        K: Into<String>,
166    {
167        let key_str = key.into();
168        self.meta.get(&key_str)?.downcast_ref::<T>()
169    }
170}