88This module provides functions for collecting client parameters from various
99sources such as user relative defaults, environment variables, and even command
1010line options.
11+
12+ There are two primary data-structures that this module deals with: normalized
13+ parameters and denormalized parameters.
14+
15+ Normalized parameters is a proper mapping object, dictionary, consisting of
16+ the parameters used to apply to a connection creation interface. The high-level
17+ interface, ``collect`` returns normalized parameters.
18+
19+ Denormalized parameters is a sequence or iterable of key-value pairs. However,
20+ the key is always a tuple whose components make up the "key-path". This is used
21+ to support sub-dictionaries like settings::
22+
23+ >>> normal_params = {
24+ 'user' : 'jwp',
25+ 'host' : 'localhost',
26+ 'settings' : {'default_statistics_target' : 200, 'search_path' : 'home,public'}
27+ }
28+
29+ Denormalized parameters are used to simplify the overriding of past parameters.
30+ For this to work with dictionaries in a general fashion, dictionary objects
31+ would need a "deep update" method.
1132"""
1233import sys
1334import os
@@ -182,7 +203,8 @@ def append_db_client_parameters(option, opt_str, value, parser):
182203 ((option .dest ,), value )
183204 )
184205
185- make_option = partial (optparse .make_option ,
206+ make_option = partial (
207+ optparse .make_option ,
186208 action = 'callback' ,
187209 callback = append_db_client_parameters
188210)
@@ -251,7 +273,7 @@ def append_db_client_x_parameters(option, opt_str, value, parser):
251273make_x_option = partial (make_option , callback = append_db_client_x_parameters )
252274
253275option_iri = make_x_option ('-I' , '--iri' ,
254- help = 'database locator string [pq://user:password@host:port/database?setting =value]' ,
276+ help = 'database locator string [pq://user:password@host:port/database?[driver_param]=valuesetting =value]' ,
255277 type = 'str' ,
256278 dest = 'pq_iri' ,
257279)
@@ -378,9 +400,7 @@ def x_pg_service(service_name, config):
378400 """
379401 Lookup service data using the `service_name`.
380402
381- A service file is very close to the format supported by
382- `configparser.RawConfigParser`, so if more dynamic access is need, just use
383- it directly. But be sure to map 'dbname' to 'database'.
403+ Be sure to map 'dbname' to 'database'.
384404 """
385405 service_file = config .get ('pg_service_file' )
386406 if service_file is None :
@@ -405,6 +425,8 @@ def x_pg_service(service_name, config):
405425 elif k .lower () == 'pg_service' :
406426 # ignore
407427 pass
428+ elif k .lower () == 'dbname' :
429+ yield (('database' ,), v )
408430 else :
409431 yield ((k ,), v )
410432
@@ -420,7 +442,11 @@ def x_pg_ldap(ldap_url, config):
420442
421443def extrapolate (iter , config = None , callbacks = default_x_callbacks ):
422444 """
423- Given an iterable of standardized
445+ Given an iterable of standardized settings,
446+
447+ [((path0, path1, ..., pathN), value)]
448+
449+ Process any callbacks.
424450 """
425451 config = config or {}
426452 for item in iter :
@@ -479,15 +505,15 @@ def resolve_pg_service_file(
479505 return os .path .join (sysconfdir , default_pg_service_filename )
480506 return None
481507
482- def standard (
483- co : "options parsed using the `DefaultParser`" = None ,
508+ def collect (
509+ parsed_options : "options parsed using the `DefaultParser`" = None ,
484510 no_defaults : "Don't build-out defaults like 'user' from getpass.getuser()" = False ,
485511 environ : "environment variables to use, `None` to disable" = os .environ ,
486512 environ_prefix : "prefix to use for collecting environment variables" = 'PG' ,
487513 default_pg_sysconfdir : "default 'PGSYSCONFDIR' to use" = None ,
488514 pg_service_file : "the pg-service file to actually use" = None ,
489515 prompt_title : "additional title to use if a prompt request is made" = '' ,
490- parameters : "base-client parameters to use(layers on top of defaults)" = (),
516+ parameters : "base-client parameters to use(applied after defaults)" = (),
491517):
492518 """
493519 Build a normalized client parameters dictionary for use with a connection
@@ -506,16 +532,19 @@ def standard(
506532
507533 if not no_defaults :
508534 d_parameters .append (defaults (environ = environ ))
509- d_parameters .extend (denormalize_parameters (dict (parameters )))
535+
536+ if parameters :
537+ d_parameters .append (denormalize_parameters (dict (parameters )))
510538
511539 if environ is not None :
512540 d_parameters .append (envvars (
513541 environ = environ ,
514542 modifier = environ_prefix .__add__
515543 ))
516- cop = getattr (co , 'db_client_parameters' , None )
544+ cop = getattr (parsed_options , 'db_client_parameters' , None )
517545 if cop :
518546 d_parameters .append (cop )
547+
519548 cpd = normalize (extrapolate (chain (* d_parameters )))
520549 if prompt_title is not None :
521550 resolve_password (cpd , prompt_title = prompt_title )
@@ -527,5 +556,5 @@ def standard(
527556 description = "print the clientparams dictionary for the environment"
528557 )
529558 (co , ca ) = p .parse_args ()
530- r = standard ( co = co , prompt_title = 'custom_prompt_title' )
559+ r = collect ( parsed_options = co , prompt_title = 'custom_prompt_title' )
531560 pprint .pprint (r )
0 commit comments