@@ -17,13 +17,15 @@ use std::sync::Arc;
1717use databend_common_base:: base:: tokio:: sync:: Mutex ;
1818use databend_common_exception:: ErrorCode ;
1919use databend_common_meta_api:: kv_pb_api:: KVPbApi ;
20+ use databend_common_meta_api:: kv_pb_api:: UpsertPB ;
2021use databend_common_meta_api:: reply:: unpack_txn_reply;
2122use databend_common_meta_api:: txn_backoff:: txn_backoff;
2223use databend_common_meta_api:: txn_cond_seq;
2324use databend_common_meta_api:: txn_op_del;
2425use databend_common_meta_api:: txn_op_put;
2526use databend_common_meta_app:: app_error:: AppError ;
2627use databend_common_meta_app:: app_error:: TxnRetryMaxTimes ;
28+ use databend_common_meta_app:: principal:: role_ident;
2729use databend_common_meta_app:: principal:: GrantObject ;
2830use databend_common_meta_app:: principal:: OwnershipInfo ;
2931use databend_common_meta_app:: principal:: OwnershipObject ;
@@ -32,6 +34,7 @@ use databend_common_meta_app::principal::RoleInfo;
3234use databend_common_meta_app:: principal:: TenantOwnershipObjectIdent ;
3335use databend_common_meta_app:: principal:: UserPrivilegeType ;
3436use databend_common_meta_app:: tenant:: Tenant ;
37+ use databend_common_meta_app:: tenant_key:: errors:: ExistError ;
3538use databend_common_meta_app:: KeyWithTenant ;
3639use databend_common_meta_cache:: Cache ;
3740use databend_common_meta_client:: ClientHandle ;
@@ -48,6 +51,7 @@ use databend_common_meta_types::Operation;
4851use databend_common_meta_types:: SeqV ;
4952use databend_common_meta_types:: TxnRequest ;
5053use databend_common_meta_types:: UpsertKV ;
54+ use databend_common_meta_types:: With ;
5155use enumflags2:: make_bitflags;
5256use fastrace:: func_name;
5357use futures:: TryStreamExt ;
@@ -175,23 +179,28 @@ impl RoleMgr {
175179impl RoleApi for RoleMgr {
176180 #[ async_backtrace:: framed]
177181 #[ fastrace:: trace]
178- async fn add_role ( & self , role_info : RoleInfo ) -> databend_common_exception:: Result < u64 > {
179- let match_seq = MatchSeq :: Exact ( 0 ) ;
180- let key = self . role_ident ( role_info. identity ( ) ) . to_string_key ( ) ;
181- let value = serialize_struct ( & role_info, ErrorCode :: IllegalUserInfoFormat , || "" ) ?;
182+ async fn add_role (
183+ & self ,
184+ info : RoleInfo ,
185+ can_replace : bool ,
186+ ) -> Result < Result < ( ) , ExistError < role_ident:: Resource > > , MetaError > {
187+ let seq = if can_replace {
188+ MatchSeq :: GE ( 0 )
189+ } else {
190+ MatchSeq :: Exact ( 0 )
191+ } ;
182192
183- let upsert_kv = self . kv_api . upsert_kv ( UpsertKV :: new (
184- & key,
185- match_seq,
186- Operation :: Update ( value) ,
187- None ,
188- ) ) ;
193+ let key = RoleIdent :: new ( & self . tenant , & info. name ) ;
194+ let req = UpsertPB :: insert ( key, info. clone ( ) ) . with ( seq) ;
195+ let res = self . kv_api . upsert_pb ( & req) . await ?;
189196
190- let res_seq = upsert_kv. await ?. added_seq_or_else ( |_v| {
191- ErrorCode :: RoleAlreadyExists ( format ! ( "Role '{}' already exists." , role_info. name) )
192- } ) ?;
197+ if !can_replace && res. prev . is_some ( ) {
198+ return Ok ( Err (
199+ RoleIdent :: new ( & self . tenant , & info. name ) . exist_error ( func_name ! ( ) )
200+ ) ) ;
201+ }
193202
194- Ok ( res_seq )
203+ Ok ( Ok ( ( ) ) )
195204 }
196205
197206 #[ async_backtrace:: framed]
0 commit comments