11use gumdrop:: Options ;
22use serde:: { Deserialize , Serialize } ;
3- use std:: collections:: HashMap ;
3+ use std:: collections:: BTreeMap ;
44use std:: fs;
55
66use crate :: utils:: { config_path, init_root_path} ;
@@ -30,12 +30,12 @@ pub struct Args {
3030 #[ serde( skip_serializing, skip_deserializing) ]
3131 pub core : bool ,
3232
33- #[ options( help = "Hostname to connect to" , meta = "HOSTNAME" ) ]
33+ #[ options( help = "Hostname (and port) to connect to" , meta = "HOSTNAME" ) ]
3434 #[ serde( default ) ]
3535 pub host : String ,
3636
3737 #[ options( help = "Database name to use" ) ]
38- #[ serde( default ) ]
38+ #[ serde( skip_serializing , skip_deserializing ) ]
3939 pub database : String ,
4040
4141 #[ options( help = "Output format (e.g., TabSeparatedWithNames, PSQL, JSONLines_Compact, Vertical, ...)" ) ]
@@ -112,15 +112,27 @@ pub struct Args {
112112}
113113
114114pub fn normalize_extras ( extras : Vec < String > , encode : bool ) -> Result < Vec < String > , Box < dyn std:: error:: Error > > {
115- let x: HashMap < & str , String > = HashMap :: from_iter ( extras. iter ( ) . map ( |e| {
115+ let mut x: BTreeMap < String , String > = BTreeMap :: new ( ) ;
116+
117+ for e in & extras {
116118 let kv: Vec < & str > = e. split ( '=' ) . collect ( ) ;
117119 if kv. len ( ) < 2 {
118- panic ! ( "Cannot parse '{}': expected key=value format" , e)
120+ return Err ( format ! ( "Cannot parse '{}': expected key=value format" , e) . into ( ) ) ;
119121 }
120- let value = kv[ 1 ..] . join ( "=" ) . to_string ( ) ;
121- // uri encode params
122- ( kv[ 0 ] , if encode { urlencoding:: encode ( & value) . into_owned ( ) } else { value } )
123- } ) ) ;
122+
123+ let key = kv[ 0 ] . to_string ( ) ;
124+ let value = kv[ 1 ..] . join ( "=" ) . trim ( ) . to_string ( ) ;
125+ let value = if value. starts_with ( '\'' ) && value. ends_with ( '\'' ) || value. starts_with ( '"' ) && value. ends_with ( '"' ) {
126+ value[ 1 ..value. len ( ) - 1 ] . to_string ( )
127+ } else {
128+ value
129+ } ;
130+
131+ let value = if encode { urlencoding:: encode ( & value) . into_owned ( ) } else { value } ;
132+
133+ x. insert ( key, value) ;
134+ }
135+
124136 let mut new_extras: Vec < String > = vec ! [ ] ;
125137 for ( key, value) in & x {
126138 new_extras. push ( format ! ( "{key}={value}" ) )
@@ -164,7 +176,6 @@ pub fn get_args() -> Result<Args, Box<dyn std::error::Error>> {
164176
165177 if args. update_defaults {
166178 args. host = args. host . or ( default_host) ;
167- args. database = args. database . or ( String :: from ( "local_dev_db" ) ) ;
168179 if args. core {
169180 args. format = args. format . or ( String :: from ( "PSQL" ) ) ;
170181 } else {
@@ -179,11 +190,6 @@ pub fn get_args() -> Result<Args, Box<dyn std::error::Error>> {
179190 args. concise = args. concise || defaults. concise ;
180191 args. hide_pii = args. hide_pii || defaults. hide_pii ;
181192
182- args. database = args
183- . database
184- . or ( args. core . then ( || String :: from ( "firebolt" ) ) . unwrap_or ( defaults. database ) )
185- . or ( String :: from ( "local_dev_db" ) ) ;
186-
187193 if args. core {
188194 args. host = args. host . or ( String :: from ( "localhost:3473" ) ) ;
189195 args. jwt = String :: from ( "" ) ;
@@ -313,4 +319,25 @@ mod tests {
313319 assert ! ( url. contains( "param=value%20with%20spaces" ) ) ;
314320 assert ! ( !url. contains( "param=value%2520with%2520spaces" ) ) ; // No double encoding
315321 }
322+
323+ #[ test]
324+ fn test_params_with_quotes ( ) {
325+ let extras = vec ! [ "param1='value with spaces'" . to_string( ) , "param2=\" value with spaces\" " . to_string( ) ] ;
326+ let result = normalize_extras ( extras, true ) . unwrap ( ) ;
327+ assert_eq ! ( result[ 0 ] , "param1=value%20with%20spaces" ) ;
328+ assert_eq ! ( result[ 1 ] , "param2=value%20with%20spaces" ) ;
329+ }
330+
331+ #[ test]
332+ fn test_params_with_spaces ( ) {
333+ let extras = vec ! [
334+ "param1= value with spaces " . to_string( ) ,
335+ "param2= \" value with spaces\" " . to_string( ) ,
336+ "param3=\" value with spaces \" " . to_string( ) ,
337+ ] ;
338+ let result = normalize_extras ( extras, true ) . unwrap ( ) ;
339+ assert_eq ! ( result[ 0 ] , "param1=value%20with%20spaces" ) ;
340+ assert_eq ! ( result[ 1 ] , "param2=value%20with%20spaces" ) ;
341+ assert_eq ! ( result[ 2 ] , "param3=%20%20value%20with%20spaces%20" ) ;
342+ }
316343}
0 commit comments