|
13 | 13 | // limitations under the License. |
14 | 14 |
|
15 | 15 | use databend_common_meta_app::app_error::AppError; |
| 16 | +use databend_common_meta_app::app_error::TxnRetryMaxTimes; |
16 | 17 | use databend_common_meta_app::data_mask::CreateDatamaskReply; |
17 | 18 | use databend_common_meta_app::data_mask::CreateDatamaskReq; |
18 | 19 | use databend_common_meta_app::data_mask::DataMaskId; |
@@ -74,84 +75,79 @@ impl<KV: kvapi::KVApi<Error = MetaError>> DatamaskApi for KV { |
74 | 75 |
|
75 | 76 | let masking_policy_id = fetch_id(self, IdGenerator::data_mask_id()).await?; |
76 | 77 |
|
77 | | - let mut trials = txn_backoff(None, func_name!()); |
78 | | - loop { |
79 | | - trials.next().unwrap()?.await; |
| 78 | + let mut txn = TxnRequest::default(); |
80 | 79 |
|
81 | | - let mut txn = TxnRequest::default(); |
| 80 | + let res = self.get_id_and_value(name_ident).await?; |
| 81 | + debug!(res :? = res, name_key :? =(name_ident); "create_data_mask"); |
82 | 82 |
|
83 | | - let res = self.get_id_and_value(name_ident).await?; |
84 | | - debug!(res :? = res, name_key :? =(name_ident); "create_data_mask"); |
85 | | - |
86 | | - let mut curr_seq = 0; |
87 | | - |
88 | | - if let Some((seq_id, seq_meta)) = res { |
89 | | - match req.create_option { |
90 | | - CreateOption::Create => { |
91 | | - return Err(AppError::DatamaskAlreadyExists( |
92 | | - name_ident.exist_error(func_name!()), |
93 | | - ) |
94 | | - .into()); |
95 | | - } |
96 | | - CreateOption::CreateIfNotExists => { |
97 | | - return Ok(CreateDatamaskReply { id: *seq_id.data }); |
98 | | - } |
99 | | - CreateOption::CreateOrReplace => { |
100 | | - let id_ident = seq_id.data.into_t_ident(name_ident.tenant()); |
101 | | - |
102 | | - txn_delete_exact(&mut txn, &id_ident, seq_meta.seq); |
103 | | - |
104 | | - curr_seq = seq_id.seq; |
105 | | - } |
106 | | - }; |
107 | | - } |
| 83 | + let mut curr_seq = 0; |
108 | 84 |
|
109 | | - // Create data mask by inserting these record: |
110 | | - // name -> id |
111 | | - // id -> policy |
112 | | - // data mask name -> data mask table id list |
113 | | - |
114 | | - let id = DataMaskId::new(masking_policy_id); |
115 | | - let id_ident = DataMaskIdIdent::new_generic(name_ident.tenant(), id); |
116 | | - let id_list_key = MaskPolicyTableIdListIdent::new_from(name_ident.clone()); |
117 | | - |
118 | | - debug!( |
119 | | - id :? =(&id_ident), |
120 | | - name_key :? =(name_ident); |
121 | | - "new datamask id" |
122 | | - ); |
123 | | - |
124 | | - { |
125 | | - let meta: DatamaskMeta = req.data_mask_meta.clone(); |
126 | | - let id_list = MaskpolicyTableIdList::default(); |
127 | | - txn.condition.push(txn_cond_eq_seq(name_ident, curr_seq)); |
128 | | - txn.condition |
129 | | - .push(txn_cond_eq_seq(&row_access_name_ident, 0)); |
130 | | - txn.if_then.extend(vec![ |
131 | | - txn_op_put_pb(name_ident, &id, None)?, // name -> db_id |
132 | | - txn_op_put_pb(&id_ident, &meta, None)?, // id -> meta |
133 | | - // TODO: Tentative retention for compatibility MaskPolicyTableIdListIdent related logic. It can be directly deleted later |
134 | | - txn_op_put_pb(&id_list_key, &id_list, None)?, // data mask name -> id_list |
135 | | - ]); |
136 | | - |
137 | | - let (succ, _responses) = send_txn(self, txn).await?; |
138 | | - |
139 | | - debug!( |
140 | | - name :? =(name_ident), |
141 | | - id :? =(&id_ident), |
142 | | - succ = succ; |
143 | | - "create_data_mask" |
144 | | - ); |
145 | | - |
146 | | - if succ { |
147 | | - break; |
| 85 | + if let Some((seq_id, seq_meta)) = res { |
| 86 | + match req.create_option { |
| 87 | + CreateOption::Create => { |
| 88 | + return Err(AppError::DatamaskAlreadyExists( |
| 89 | + name_ident.exist_error(func_name!()), |
| 90 | + ) |
| 91 | + .into()); |
148 | 92 | } |
149 | | - } |
| 93 | + CreateOption::CreateIfNotExists => { |
| 94 | + return Ok(CreateDatamaskReply { id: *seq_id.data }); |
| 95 | + } |
| 96 | + CreateOption::CreateOrReplace => { |
| 97 | + let id_ident = seq_id.data.into_t_ident(name_ident.tenant()); |
| 98 | + |
| 99 | + txn_delete_exact(&mut txn, &id_ident, seq_meta.seq); |
| 100 | + |
| 101 | + curr_seq = seq_id.seq; |
| 102 | + } |
| 103 | + }; |
| 104 | + } |
| 105 | + |
| 106 | + // Create data mask by inserting these record: |
| 107 | + // name -> id |
| 108 | + // id -> policy |
| 109 | + // data mask name -> data mask table id list |
| 110 | + |
| 111 | + let id = DataMaskId::new(masking_policy_id); |
| 112 | + let id_ident = DataMaskIdIdent::new_generic(name_ident.tenant(), id); |
| 113 | + let id_list_key = MaskPolicyTableIdListIdent::new_from(name_ident.clone()); |
| 114 | + |
| 115 | + debug!( |
| 116 | + id :? =(&id_ident), |
| 117 | + name_key :? =(name_ident); |
| 118 | + "new datamask id" |
| 119 | + ); |
| 120 | + |
| 121 | + { |
| 122 | + let meta: DatamaskMeta = req.data_mask_meta.clone(); |
| 123 | + let id_list = MaskpolicyTableIdList::default(); |
| 124 | + txn.condition.push(txn_cond_eq_seq(name_ident, curr_seq)); |
| 125 | + txn.condition |
| 126 | + .push(txn_cond_eq_seq(&row_access_name_ident, 0)); |
| 127 | + txn.if_then.extend(vec![ |
| 128 | + txn_op_put_pb(name_ident, &id, None)?, // name -> db_id |
| 129 | + txn_op_put_pb(&id_ident, &meta, None)?, // id -> meta |
| 130 | + // TODO: Tentative retention for compatibility MaskPolicyTableIdListIdent related logic. It can be directly deleted later |
| 131 | + txn_op_put_pb(&id_list_key, &id_list, None)?, // data mask name -> id_list |
| 132 | + ]); |
150 | 133 | } |
151 | 134 |
|
152 | | - Ok(CreateDatamaskReply { |
153 | | - id: masking_policy_id, |
154 | | - }) |
| 135 | + let (succ, _responses) = send_txn(self, txn).await?; |
| 136 | + |
| 137 | + debug!( |
| 138 | + name :? =(name_ident), |
| 139 | + id :? =(&id_ident), |
| 140 | + succ = succ; |
| 141 | + "create_data_mask" |
| 142 | + ); |
| 143 | + |
| 144 | + if succ { |
| 145 | + Ok(CreateDatamaskReply { |
| 146 | + id: masking_policy_id, |
| 147 | + }) |
| 148 | + } else { |
| 149 | + Err(KVAppError::from(TxnRetryMaxTimes::new(func_name!(), 1))) |
| 150 | + } |
155 | 151 | } |
156 | 152 |
|
157 | 153 | async fn drop_data_mask( |
|
0 commit comments