Changeset 323:2fb49308319a

Show
Ignore:
Timestamp:
08/21/11 02:44:03 (9 months ago)
Author:
Anselm Lingnau <anselm@…>
Branch:
default
Message:

Configuration parameter system reworked.
This adds a list of ?official? configuration parameters together with their
types, default values, and explanatory messages. An extended method,
DB::get_config_x(), is used to retrieve all of this info, and DB::get_config()
is changed to return the default value from the list if the parameter is not
set in the database.

In the pl-conf command, there are some new --query suboptions: --all outputs
all configuration parameters, not just those that are in the current list
database; --modified outputs only those parameters whose values differ from
the built-in defaults; and --defaults outputs the built-in default values
of parameters rather than their actual values.

This change is really for the benefit of Project Guinevere, which needs to
be able to produce a list configuration page containing all possible parameters
rather than just the ones that happen to be in the database at that point.
We will still have to go through the files and adapt all the calls to
get_config() to remove the hard-coded defaults, and we can also get rid of the
big default parameter list in DB.pm.

Files:
1 added
3 modified

Legend:

Unmodified
Added
Removed
  • MANIFEST

    r303 r323  
    3636lib/Lancelot/Bounce/tonline.pm 
    3737lib/Lancelot/Bounce/yahoo.pm 
     38lib/Lancelot/ConfigItems.pm 
    3839lib/Lancelot/DB.pm 
    3940lib/Lancelot/GetOpt.pm 
  • bin/pl-conf

    r313 r323  
    77=head1 SYNOPSIS 
    88 
    9   pl-conf [--query|-q] [--valueonly|-h] list@domain [parameter ...] 
     9  pl-conf [--query|-q] [--all|-A] [--modified|-M] [--defaults|-D] 
     10            [--valueonly|-h] list@domain [parameter ...] 
    1011  pl-conf [--set|-s] list@domain ["parameter = value" ...] 
    1112  pl-conf [--import|-i] [--onlynew|-n] list@domain [file ...] 
     
    2728 
    2829With the B<--query> (or B<-q>) option, B<pl-conf> will print either 
    29 all of the configuration parameters (if no parameter names are given) 
    30 or the specified parameters to standard output, like 
     30all of the configuration parameters in the database (if no parameter 
     31names are given) or the specified parameters to standard output, like 
    3132 
    3233  list.address = test@example.com 
     
    4243line.  This is convenient if the parameter value is to be used, e.g., 
    4344in a shell script. 
     45 
     46With the B<--modified> (or B<-M>) option, B<--query> only lists those 
     47parameters whose values differ from their built-in defaults. With the 
     48B<--defaults> (or B<-D>) option, the built-in default values of 
     49parameters are displayed instead of their actual values. With the 
     50B<--all> (or B<-A>) option, all parameters known to Project Lancelot 
     51are displayed, not just those that actually occur in the database of 
     52the list being considered. 
    4453 
    4554The output of B<pl-conf --query> is suitable as input for 
     
    142151Introduces a command-line alias for a mailing list. 
    143152 
     153=item B<--all>, B<-A> 
     154 
     155With B<--query>, outputs all configuration parameters known to Project 
     156Lancelot, not just those that actually occur in the database of the 
     157current list. 
     158 
     159=item B<--defaults>, B<-D> 
     160 
     161With B<--query>, causes the program to output the built-in default values 
     162of parameters rather than their actual values. 
     163 
    144164=item B<--delete>, B<-d> 
    145165 
     
    162182this specifies the list that the given list's database should be merged 
    163183into. 
     184 
     185=item B<--modified>, B<-M> 
     186 
     187With B<--query>, outputs only those parameter whose values differ from 
     188their built-in default values. 
    164189 
    165190=item B<--onlynew>, B<-n> 
     
    257282use Lancelot::Log qw/log/; 
    258283 
    259 my (%opts); 
     284my %opts = ( all => 0 ); 
    260285 
    261286GetOptions(\%opts, -defaults, -argvmin => 1, "no list address specified", 
    262287           "query|q?", "set|s?", "import|i?", "delete|d?", "valueonly|h?", 
    263288           "merge|m?", "unmerge|u?", "alias|a?", "into=", 
     289           "defaults|D?", "modified|M?", "all|A?", 
    264290           "onlynew|n?", "edit|e?", "user|u="); 
    265291 
    266 pod2usage( -message => "$0: need one of --query, --set, --import, --delete", 
    267            -exitvalue => 2) 
     292pod2usage( -message => "$0: need one of --query, --set, --import, --delete, --merge, --unmerge, --alias", 
     293           -exitvalue => 2 ) 
    268294    if $opts{alias} + $opts{query} + $opts{set} + $opts{import} 
    269295           + $opts{delete} + $opts{edit} + $opts{merge} + $opts{unmerge} != 1 
    270         || ($opts{valueonly} && !$opts{query}) 
     296        || (($opts{valueonly} || $opts{defaults} || $opts{modified} 
     297            || $opts{all}) && !$opts{query}) 
    271298        || ($opts{onlynew} && !$opts{import}) 
    272299        || ($opts{into} && !$opts{merge}); 
     
    284311            ($pattern = $ARGV[0]) =~ s/\./\\./g; $pattern =~ s/\*/.*/g; 
    285312        } 
    286         @parameters = grep { /$pattern/o } $db->config_names; 
     313        @parameters = grep { /$pattern/o } 
     314            $db->config_names({ all => $opts{all} }); 
    287315        $opts{valueonly} = 0; 
    288316    } 
    289317    foreach my $p (sort @parameters) { 
     318        my ($v, $status, $default) = $db->get_config_x($p); 
     319        next if $opts{modified} && $status < 2;  
     320        $v = $default if $opts{defaults}; 
    290321        print "$p = " unless $opts{valueonly}; 
    291         my ($v) = $db->get_config($p); 
    292322        if ($v =~ /^\s+/ || $v =~ /\s+$/) { 
    293323            $v =~ s/\"/\\\"/g; 
  • lib/Lancelot/DB.pm

    r321 r323  
    7171 
    7272use Lancelot::Log qw/log/; 
     73use Lancelot::ConfigItems; 
    7374 
    7475# Here are the SQL definitions Project Lancelot uses when initialising a 
     
    383384    my ($local, $domain) = split /\@/, $listaddr; 
    384385 
     386    Lancelot::ConfigItems::init(); 
     387 
    385388    my $home; 
    386389    my $user = $optref->{user}; 
     
    825828sub get_config { 
    826829    my ($self, $key) = @_; 
    827     my $value = ($self->{dbh}->selectrow_array("SELECT value FROM config WHERE list_id=? AND key=?", 
    828                                                {}, $self->{list_id}, $key))[0]; 
    829     return $value; 
     830    my $config = $self->{dbh}->selectrow_hashref( 
     831        "SELECT value FROM config WHERE list_id=? AND key=?", 
     832        {}, $self->{list_id}, $key); 
     833    if (!$config) { 
     834        my $cfgvar = Lancelot::ConfigItems->config_item($key); 
     835        log "warn", "unknown configuration variable $key" unless $cfgvar; 
     836        return $cfgvar? $cfgvar->{default} : undef; 
     837    } 
     838    return $config->{value}; 
     839} 
     840 
     841=item C<get_config_x> 
     842 
     843  $value = $db->get_config_x($key); 
     844 
     845Returns a tuple (C<$value>, C<$status>, C<$default>, C<$type>, 
     846C<$help>) where C<$value> is the current value of the configuration 
     847parameter and C<$status> is 0 if the parameter is not set in the 
     848database (i.e., C<$value> is the internal hard-coded default), 1 if 
     849the parameter is set in the database but equals the internal 
     850hard-coded default, 2 if the parameter is set in the database but does 
     851not I<have> an internal hard-coded default (because it is used by a 
     852processing module that didn't register it with the internal list), and 
     8533 if the parameter is set in the database and differs from the 
     854hard-coded default. 
     855 
     856C<$type> is one of BOOL, INT, STR, and SEL and gives the type of value 
     857that the configuration parameter is supposed to take on. 
     858 
     859This is mostly for the benefit of the Project Guinevere web front end, 
     860but also pl-conf(1). 
     861 
     862=cut 
     863 
     864sub get_config_x { 
     865    my ($self, $key) = @_; 
     866    my $cfgvar = Lancelot::ConfigItems->config_item($key); 
     867    my $config = $self->{dbh}->selectrow_hashref( 
     868        "SELECT value FROM config WHERE list_id=? AND key=?", 
     869        {}, $self->{list_id}, $key); 
     870    my @result; 
     871    if (!$config) { 
     872        if (!$cfgvar) { 
     873            @result = (undef, 4, undef, undef, undef); 
     874        } else { 
     875            @result = ($cfgvar->{default}, 0, $cfgvar->{default}, 
     876                $cfgvar->{type}, $cfgvar->{help}); 
     877        } 
     878    } elsif (!$cfgvar) { 
     879        @result = ($config->{value}, 2, undef, undef, undef); 
     880    } else { 
     881        if ($config->{value} eq $cfgvar->{default}) { 
     882            @result = ($config->{value}, 1); 
     883        } else { 
     884            @result = ($config->{value}, 3); 
     885        } 
     886        push @result, $cfgvar->{default}, $cfgvar->{type}, $cfgvar->{help}; 
     887    } 
     888    return @result; 
    830889} 
    831890 
     
    9521011 
    9531012sub config_names { 
    954     my ($self) = @_; 
    955     my ($ref) = $self->{dbh}->selectcol_arrayref("SELECT key FROM config WHERE list_id=?", 
    956                                                  {}, $self->{list_id}); 
    957     return @$ref; 
     1013    my ($self, $optref) = @_; 
     1014    my %names = map { $_ => 1 } @{$self->{dbh}->selectcol_arrayref( 
     1015                                      "SELECT key FROM config WHERE list_id=?", 
     1016                                      {}, $self->{list_id})}; 
     1017    if ($optref->{all}) { 
     1018        $names{$_} = 1 foreach Lancelot::ConfigItems->config_item_keys(); 
     1019    } 
     1020    return keys %names; 
    9581021} 
    9591022