@@ -16,7 +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 ;
19+ use std:: collections :: HashSet ;
2020use std:: { collections:: HashMap , fmt:: Display , sync:: Arc } ;
2121use tokio:: sync:: RwLock ;
2222
@@ -58,7 +58,8 @@ pub struct Client {
5858 database : Option < String > ,
5959 authentication : Authentication ,
6060 compression : Compression ,
61- options : HashMap < Cow < ' static , str > , String > ,
61+ roles : HashSet < String > ,
62+ options : HashMap < String , String > ,
6263 headers : HashMap < String , String > ,
6364 products_info : Vec < ProductInfo > ,
6465 validation : bool ,
@@ -122,6 +123,7 @@ impl Client {
122123 database : None ,
123124 authentication : Authentication :: default ( ) ,
124125 compression : Compression :: default ( ) ,
126+ roles : HashSet :: new ( ) ,
125127 options : HashMap :: new ( ) ,
126128 headers : HashMap :: new ( ) ,
127129 products_info : Vec :: default ( ) ,
@@ -228,27 +230,32 @@ impl Client {
228230 self
229231 }
230232
231- /// Set the [role ] to use when executing statements with this `Client` instance.
233+ /// Configure the [roles ] to use when executing statements with this `Client` instance.
232234 ///
233- /// Overrides any role previously set by [`Client::with_role()`] or [`Client::with_option()`].
235+ /// Overrides any roles previously set by this method or [`Client::with_option`].
236+ ///
237+ /// An empty iterator may be passed to clear the set roles.
234238 ///
235239 /// This setting is copied into cloned clients.
236240 ///
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.
241+ /// [roles]: https://clickhouse.com/docs/operations/access-rights#role-management
244242 ///
245- /// Overrides any role previously set by [`Client::with_role()`] or [`Client::with_option()`].
243+ /// # Examples
246244 ///
247- /// This setting is copied into cloned clients.
245+ /// ```
246+ /// # use clickhouse::Client;
247+ ///
248+ /// # Single role
249+ /// let client = Client::default().with_roles(["foo"]);
248250 ///
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 ) ;
251+ /// # Multiple roles
252+ /// let client = Client::default().with_roles(["foo", "bar", "baz"]);
253+ ///
254+ /// # Clear all previously set roles
255+ /// let client = Client::default().with_roles([]);
256+ /// ```
257+ pub fn with_roles ( mut self , roles : impl IntoIterator < Item = impl Into < String > > ) -> Self {
258+ self . set_roles ( roles) ;
252259 self
253260 }
254261
@@ -303,7 +310,7 @@ impl Client {
303310 /// Client::default().with_option("allow_nondeterministic_mutations", "1");
304311 /// ```
305312 pub fn with_option ( mut self , name : impl Into < String > , value : impl Into < String > ) -> Self {
306- self . options . insert ( Cow :: Owned ( name. into ( ) ) , value. into ( ) ) ;
313+ self . options . insert ( name. into ( ) , value. into ( ) ) ;
307314 self
308315 }
309316
@@ -472,22 +479,15 @@ impl Client {
472479 /// Used internally to modify the options map of an _already cloned_
473480 /// [`Client`] instance.
474481 pub ( crate ) fn add_option ( & mut self , name : impl Into < String > , value : impl Into < String > ) {
475- self . options . insert ( Cow :: Owned ( name. into ( ) ) , value. into ( ) ) ;
482+ self . options . insert ( name. into ( ) , value. into ( ) ) ;
476483 }
477484
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" ) ;
485+ pub ( crate ) fn set_roles ( & mut self , roles : impl IntoIterator < Item = impl Into < String > > ) {
486+ // Make sure we overwrite any role manually set by the user via `with_option()`.
487+ self . options . remove ( "role" ) ;
482488
483- match role {
484- Some ( role) => {
485- self . options . insert ( key, role) ;
486- }
487- None => {
488- self . options . remove ( & key) ;
489- }
490- }
489+ self . roles . clear ( ) ;
490+ self . roles . extend ( roles. into_iter ( ) . map ( Into :: into) ) ;
491491 }
492492
493493 /// Use a mock server for testing purposes.
0 commit comments