Skip to content

Commit 29cb512

Browse files
authored
refactor(management): simplify UserApi using upsert_pb/get_pb patterns (#19413)
1 parent 081742d commit 29cb512

File tree

19 files changed

+383
-480
lines changed

19 files changed

+383
-480
lines changed

src/meta/app/src/principal/tenant_user_ident.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,14 @@ impl TenantUserIdent {
3535
}
3636

3737
mod kvapi_impl {
38-
38+
use databend_common_exception::ErrorCode;
3939
use databend_meta_kvapi::kvapi;
4040

4141
use crate::principal::TenantUserIdent;
42+
use crate::principal::UserIdentity;
4243
use crate::principal::UserInfo;
44+
use crate::tenant_key::errors::ExistError;
45+
use crate::tenant_key::errors::UnknownError;
4346
use crate::tenant_key::resource::TenantResource;
4447

4548
pub struct Resource;
@@ -50,16 +53,24 @@ mod kvapi_impl {
5053
type ValueType = UserInfo;
5154
}
5255

56+
impl From<ExistError<Resource, UserIdentity>> for ErrorCode {
57+
fn from(err: ExistError<Resource, UserIdentity>) -> Self {
58+
ErrorCode::UserAlreadyExists(format!("User {} already exists.", err.name().display()))
59+
}
60+
}
61+
62+
impl From<UnknownError<Resource, UserIdentity>> for ErrorCode {
63+
fn from(err: UnknownError<Resource, UserIdentity>) -> Self {
64+
ErrorCode::UnknownUser(format!("User {} does not exist.", err.name().display()))
65+
}
66+
}
67+
5368
impl kvapi::Value for UserInfo {
5469
type KeyType = TenantUserIdent;
5570
fn dependency_keys(&self, _key: &Self::KeyType) -> impl IntoIterator<Item = String> {
5671
[]
5772
}
5873
}
59-
60-
// // Use these error types to replace usage of ErrorCode if possible.
61-
// impl From<ExistError<Resource>> for ErrorCode {
62-
// impl From<UnknownError<Resource>> for ErrorCode {
6374
}
6475

6576
#[cfg(test)]

src/query/management/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ mod warehouse;
3030

3131
mod client_session;
3232
pub mod errors;
33+
pub use errors::meta_service_error;
3334
mod procedure;
3435
pub mod task;
3536
mod workload;

src/query/management/src/procedure/procedure_mgr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ impl ProcedureMgr {
6262
}
6363

6464
/// Add a PROCEDURE to /tenant/procedure-name.
65+
/// Returns `ExistError` if the procedure already exists and `overriding` is false.
6566
#[async_backtrace::framed]
6667
pub async fn create_procedure(
6768
&self,

src/query/management/src/user/user_api.rs

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,44 +12,65 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use databend_common_exception::Result;
1615
use databend_common_meta_app::principal::UserIdentity;
1716
use databend_common_meta_app::principal::UserInfo;
18-
use databend_common_meta_app::schema::CreateOption;
17+
use databend_common_meta_app::principal::tenant_user_ident::Resource as UserIdentResource;
18+
use databend_common_meta_app::tenant_key::errors::ExistError;
19+
use databend_common_meta_app::tenant_key::errors::UnknownError;
1920
use databend_meta_kvapi::kvapi::ListKVReply;
20-
use databend_meta_types::MatchSeq;
21+
use databend_meta_types::MetaError;
2122
use databend_meta_types::SeqV;
2223

2324
#[async_trait::async_trait]
2425
pub trait UserApi: Sync + Send {
25-
async fn add_user(&self, user_info: UserInfo, create_option: &CreateOption) -> Result<()>;
26+
/// Create a user.
27+
/// Returns `Ok(Ok(()))` on success.
28+
/// Returns `Ok(Err(ExistError))` if the user already exists and `overriding` is false.
29+
async fn create_user(
30+
&self,
31+
user_info: UserInfo,
32+
overriding: bool,
33+
) -> Result<Result<(), ExistError<UserIdentResource, UserIdentity>>, MetaError>;
2634

27-
async fn get_user(&self, user: UserIdentity, seq: MatchSeq) -> Result<SeqV<UserInfo>>;
35+
/// Get a user by identity.
36+
/// Returns `Some(SeqV)` if the user exists, `None` otherwise.
37+
async fn get_user(&self, user: &UserIdentity) -> Result<Option<SeqV<UserInfo>>, MetaError>;
2838

29-
async fn get_users(&self) -> Result<Vec<SeqV<UserInfo>>>;
39+
async fn get_users(&self) -> Result<Vec<SeqV<UserInfo>>, MetaError>;
3040

3141
/// Just get user count in meta
32-
async fn get_raw_users(&self) -> Result<ListKVReply>;
42+
async fn get_raw_users(&self) -> Result<ListKVReply, MetaError>;
3343

34-
/// General user's grants update.
44+
/// Update a user in place.
3545
///
36-
/// It fetches the user that matches the specified seq number, update it in place, then write it back with the seq it sees.
46+
/// This method internally calls `get_user` to fetch the current user state,
47+
/// applies the update function, then writes back with optimistic concurrency control.
48+
/// The seq from the internal `get_user` is used for CAS (compare-and-swap).
3749
///
38-
/// Seq number ensures there is no other write happens between get and set.
39-
/// Example:
40-
/// ```ignore
41-
/// self.update_user_with(user_ident, MatchSeq::GE(1), |ui: &mut UserInfo| ui.update_auth_option(foo())).await;
42-
/// ```
50+
/// Returns `Ok(Ok(new_seq))` on success.
51+
/// Returns `Ok(Err(UnknownError))` if the user does not exist or seq mismatch.
4352
async fn update_user_with<F>(
4453
&self,
45-
user: UserIdentity,
46-
seq: MatchSeq,
54+
user: &UserIdentity,
4755
f: F,
48-
) -> Result<Option<u64>>
56+
) -> Result<Result<u64, UnknownError<UserIdentResource, UserIdentity>>, MetaError>
4957
where
5058
F: FnOnce(&mut UserInfo) + Send;
5159

52-
async fn upsert_user_info(&self, user: &UserInfo, seq: MatchSeq) -> Result<u64>;
60+
/// Upsert user info with exact seq matching.
61+
/// Returns `Ok(Ok(new_seq))` on success.
62+
/// Returns `Ok(Err(UnknownError))` if seq mismatch.
63+
async fn upsert_user_info(
64+
&self,
65+
user: &UserInfo,
66+
seq: u64,
67+
) -> Result<Result<u64, UnknownError<UserIdentResource, UserIdentity>>, MetaError>;
5368

54-
async fn drop_user(&self, user: UserIdentity, seq: MatchSeq) -> Result<()>;
69+
/// Drop a user.
70+
/// Returns `Ok(Ok(()))` if the user was dropped.
71+
/// Returns `Ok(Err(UnknownError))` if the user did not exist.
72+
async fn drop_user(
73+
&self,
74+
user: &UserIdentity,
75+
) -> Result<Result<(), UnknownError<UserIdentResource, UserIdentity>>, MetaError>;
5576
}

0 commit comments

Comments
 (0)