1
+ use std:: collections:: HashMap ;
1
2
use std:: env:: var;
2
3
use std:: path:: { Path , PathBuf } ;
3
4
@@ -33,7 +34,7 @@ pub use ssl_mode::PgSslMode;
33
34
/// | `password` | `None` | Password to be used if the server demands password authentication. |
34
35
/// | `port` | `5432` | Port number to connect to at the server host, or socket file name extension for Unix-domain connections. |
35
36
/// | `dbname` | `None` | The database name. |
36
- /// | `options` | `None` | The command-line options to send to the server at connection start. |
37
+ /// | `options` | `None` | The runtime parameters to send to the server at connection start. |
37
38
///
38
39
/// The URI scheme designator can be either `postgresql://` or `postgres://`.
39
40
/// Each of the URI parts is optional.
@@ -86,7 +87,7 @@ pub struct PgConnectOptions {
86
87
pub ( crate ) statement_cache_capacity : usize ,
87
88
pub ( crate ) application_name : Option < String > ,
88
89
pub ( crate ) log_settings : LogSettings ,
89
- pub ( crate ) options : Option < String > ,
90
+ pub ( crate ) options : HashMap < String , String > ,
90
91
}
91
92
92
93
impl Default for PgConnectOptions {
@@ -147,7 +148,9 @@ impl PgConnectOptions {
147
148
statement_cache_capacity : 100 ,
148
149
application_name : var ( "PGAPPNAME" ) . ok ( ) ,
149
150
log_settings : Default :: default ( ) ,
150
- options : var ( "PGOPTIONS" ) . ok ( ) ,
151
+ options : var ( "PGOPTIONS" )
152
+ . and_then ( |v| Ok ( parse_options ( & v) . unwrap_or_default ( ) . into_iter ( ) . collect ( ) ) )
153
+ . unwrap_or_default ( ) ,
151
154
}
152
155
}
153
156
@@ -329,10 +332,17 @@ impl PgConnectOptions {
329
332
/// ```rust
330
333
/// # use sqlx_core::postgres::PgConnectOptions;
331
334
/// let options = PgConnectOptions::new()
332
- /// .options("-c geqo= off -c statement_timeout= 5min");
335
+ /// .options(&[(" geqo", " off"), (" statement_timeout", " 5min")] );
333
336
/// ```
334
- pub fn options ( mut self , options : & str ) -> Self {
335
- self . options = Some ( options. to_owned ( ) ) ;
337
+ pub fn options < K , V , I > ( mut self , options : I ) -> Self
338
+ where
339
+ K : ToString ,
340
+ V : ToString ,
341
+ I : IntoIterator < Item = ( K , V ) > ,
342
+ {
343
+ for ( k, v) in options {
344
+ self . options . insert ( k. to_string ( ) , v. to_string ( ) ) ;
345
+ }
336
346
self
337
347
}
338
348
@@ -353,6 +363,24 @@ impl PgConnectOptions {
353
363
}
354
364
}
355
365
366
+ /// Parse a libpq style options string
367
+ pub ( crate ) fn parse_options ( input : & str ) -> Option < Vec < ( String , String ) > > {
368
+ let mut options = Vec :: new ( ) ;
369
+ for part in input. split ( ' ' ) {
370
+ let part = part. trim ( ) ;
371
+ if part. is_empty ( ) || part == "-c" {
372
+ continue ;
373
+ }
374
+ let pair = part. splitn ( 2 , '=' ) . collect :: < Vec < _ > > ( ) ;
375
+ if pair. len ( ) != 2 {
376
+ return None ;
377
+ }
378
+ options. push ( ( pair[ 0 ] . to_string ( ) , pair[ 1 ] . to_string ( ) ) ) ;
379
+ }
380
+
381
+ Some ( options)
382
+ }
383
+
356
384
fn default_host ( port : u16 ) -> String {
357
385
// try to check for the existence of a unix socket and uses that
358
386
let socket = format ! ( ".s.PGSQL.{}" , port) ;
0 commit comments