@@ -16,6 +16,7 @@ pub use clickhouse_macros::Row;
1616use clickhouse_types:: { Column , DataTypeNode } ;
1717
1818use crate :: _priv:: row_insert_metadata_query;
19+ use std:: borrow:: Cow ;
1920use std:: { collections:: HashMap , fmt:: Display , sync:: Arc } ;
2021use tokio:: sync:: RwLock ;
2122
@@ -57,7 +58,7 @@ pub struct Client {
5758 database : Option < String > ,
5859 authentication : Authentication ,
5960 compression : Compression ,
60- options : HashMap < String , String > ,
61+ options : HashMap < Cow < ' static , str > , String > ,
6162 headers : HashMap < String , String > ,
6263 products_info : Vec < ProductInfo > ,
6364 validation : bool ,
@@ -227,6 +228,30 @@ impl Client {
227228 self
228229 }
229230
231+ /// Set the [role] to use when executing statements with this `Client` instance.
232+ ///
233+ /// Overrides any role previously set by [`Client::with_role()`] or [`Client::with_option()`].
234+ ///
235+ /// This setting is copied into cloned clients.
236+ ///
237+ /// [role]: https://clickhouse.com/docs/operations/access-rights#role-management
238+ pub fn with_role ( mut self , role : impl Into < String > ) -> Self {
239+ self . set_role ( Some ( role. into ( ) ) ) ;
240+ self
241+ }
242+
243+ /// Execute subsequent statements with this `Client` instance without any explicit [role] set.
244+ ///
245+ /// Overrides any role previously set by [`Client::with_role()`] or [`Client::with_option()`].
246+ ///
247+ /// This setting is copied into cloned clients.
248+ ///
249+ /// [role]: https://clickhouse.com/docs/operations/access-rights#role-management
250+ pub fn with_default_role ( mut self ) -> Self {
251+ self . set_role ( None ) ;
252+ self
253+ }
254+
230255 /// A JWT access token to authenticate with ClickHouse.
231256 /// JWT token authentication is supported in ClickHouse Cloud only.
232257 /// Should not be called after [`Client::with_user`] or
@@ -278,7 +303,7 @@ impl Client {
278303 /// Client::default().with_option("allow_nondeterministic_mutations", "1");
279304 /// ```
280305 pub fn with_option ( mut self , name : impl Into < String > , value : impl Into < String > ) -> Self {
281- self . options . insert ( name. into ( ) , value. into ( ) ) ;
306+ self . options . insert ( Cow :: Owned ( name. into ( ) ) , value. into ( ) ) ;
282307 self
283308 }
284309
@@ -447,7 +472,22 @@ impl Client {
447472 /// Used internally to modify the options map of an _already cloned_
448473 /// [`Client`] instance.
449474 pub ( crate ) fn add_option ( & mut self , name : impl Into < String > , value : impl Into < String > ) {
450- self . options . insert ( name. into ( ) , value. into ( ) ) ;
475+ self . options . insert ( Cow :: Owned ( name. into ( ) ) , value. into ( ) ) ;
476+ }
477+
478+ pub ( crate ) fn set_role ( & mut self , role : Option < String > ) {
479+ // By setting the role via `options`, we can be sure we've overwritten any role
480+ // manually set by the user with `with_option()`.
481+ let key = Cow :: Borrowed ( "role" ) ;
482+
483+ match role {
484+ Some ( role) => {
485+ self . options . insert ( key, role) ;
486+ }
487+ None => {
488+ self . options . remove ( & key) ;
489+ }
490+ }
451491 }
452492
453493 /// Use a mock server for testing purposes.
0 commit comments