File Coverage

blib/lib/MySQL/Config.pm
Criterion Covered Total %
statement 71 75 94.6
branch 28 36 77.7
condition 7 11 63.6
subroutine 8 8 100.0
pod 2 2 100.0
total 116 132 87.8


line stmt bran cond sub pod time code
1             package MySQL::Config;
2              
3             # ----------------------------------------------------------------------
4             # MySQL::Config -
5             # Copyright (C) 2003 darren chamberlain
6             # ----------------------------------------------------------------------
7              
8 5     5   3739 use strict;
  5         7  
  5         180  
9 5     5   27 use base qw(Exporter);
  5         8  
  5         581  
10 5     5   34 use vars qw($VERSION $GLOBAL_CNF @EXPORT @EXPORT_OK);
  5         9  
  5         459  
11              
12 5     5   28 use Carp qw(carp);
  5         8  
  5         340  
13 5     5   23 use File::Spec;
  5         6  
  5         5182  
14              
15             $VERSION = '1.04';
16             $GLOBAL_CNF = "/etc/%s.cnf" unless defined $GLOBAL_CNF;
17             @EXPORT = qw(load_defaults);
18             @EXPORT_OK = qw(parse_defaults);
19              
20             # ======================================================================
21             # --- Public Functions ---
22             # ======================================================================
23              
24             sub load_defaults {
25 7     7 1 27888 my ($conf_file, $groups, $argc, $argv) = @_;
26 7         53 my ($user_cnf, $ini, $field);
27 7         34 $ini = [ ];
28              
29             # ------------------------------------------------------------------
30             # Sanity checking:
31             # * $conf_file should be a string, defaults to "my"
32             # * $groups should be a ref to an array
33             # * $argc should be a ref to a scalar
34             # * $argv should be a ref to an array
35             # ------------------------------------------------------------------
36 7 100 66     248 $conf_file = "my" unless defined $conf_file && ! ref($conf_file);
37 7 50       52 $groups = [ $groups ]
38             unless ref $groups eq 'ARRAY';
39              
40 7 100       59 if (defined $argc) {
41 6 50       40 $argc = \$argc
42             unless ref $argc eq 'SCALAR';
43             }
44             else {
45 1         10 $argc = \(my $i = 0);
46             }
47              
48 7 100       43 $argv = \@ARGV unless defined $argv;
49 7 50       44 $argv = [ $argv ]
50             unless ref $argv eq 'ARRAY';
51              
52 7         160 $user_cnf = File::Spec->catfile($ENV{HOME}, ".$conf_file.cnf");
53              
54             # ------------------------------------------------------------------
55             # Parse the global config and user's config
56             # ------------------------------------------------------------------
57 7         82 _parse($ini, sprintf $GLOBAL_CNF, $conf_file);
58 7         27 _parse($ini, $user_cnf);
59              
60             # ------------------------------------------------------------------
61             # Pull out the appropriate pieces, based on @$groups
62             # ------------------------------------------------------------------
63 7 50       29 @$groups = map { $_->[0] } @$ini unless @$groups;
  0         0  
64 7         27 $groups = join '|', map { quotemeta($_) } @$groups;
  10         50  
65              
66 63         238 push @$argv, map { $$argc++; sprintf "--%s=%s", $_->[1], $_->[2] }
  63         206  
  182         814  
67 7         1927 grep { $_->[0] =~ /^$groups$/ } @$ini;
68              
69 7         90 1;
70             }
71              
72             sub parse_defaults {
73 3     3 1 23633 my ($conf_file, $groups) = @_;
74 3         8 my ($count, $argv, %ini);
75 3         7 $argv = [ ];
76              
77 3         12 load_defaults($conf_file, $groups, \$count, $argv);
78              
79 3         9 for (@$argv) {
80 31 50       133 next unless /^--(.*?)=(.*)$/;
81 31         77 my $name = $1;
82 31         48 my $value = $2;
83              
84 31 100       68 if ($value =~ /=/) {
85 11 100 66     46 $ini{ $name } = { }
86             unless exists($ini{ $name }) &&
87             ref($ini{ $name }) eq 'HASH';
88 11         36 my ($subname, $subvalue) = split /\s*=\s*/, $value, 2;
89 11         31 $ini{ $name }->{ $subname } = $subvalue;
90             }
91             else {
92 20         68 $ini{ $name } = $value;
93             }
94             }
95              
96 3 50       41 return wantarray ? %ini : \%ini;
97             }
98              
99             # ======================================================================
100             # --- Private Functions ---
101             # ======================================================================
102              
103             # ----------------------------------------------------------------------
104             # _parse($file)
105             #
106             # Parses an ini-style file into an array of [ group, name, value ]
107             # array refs.
108             # ----------------------------------------------------------------------
109             sub _parse {
110 14     14   25 my $ini = shift;
111 14         29 my $file = shift;
112 14         20 my $current;
113 14         79 local ($_, *INI);
114              
115 14 100 66     498 return { } unless -f $file && -r _;
116              
117 7   50     38 $ini ||= [ ];
118 7 50       465 unless (open INI, $file) {
119 0         0 carp "Couldn't open $file: $!";
120 0         0 return { };
121             }
122 7         235 while () {
123 322         1456 s/[;#].*$//;
124 322         1095 s/^\s*//;
125 322         1656 s/\s*$//;
126              
127 322 100       961 next unless length;
128              
129 203 100       733 /^\s*\[(.*)\]\s*$/
130             and $current = $1, next;
131              
132 182 100       672 $_ = join '=', $_, 1
133             unless /=/;
134              
135 182         760 my ($n, $v) = split /\s*=\s*/, $_, 2;
136 182 100       545 if ($v =~ /\s/) {
137 14         37 $v =~ s/"/\\"/g;
138 14         33 $v = qq("$v")
139             }
140              
141 182         1081 push @$ini, [ $current, $n, $v ];
142             }
143              
144 7 50       127 unless (close INI) {
145 0         0 carp "Couldn't close $file: $!";
146             }
147              
148 7         37 return $ini;
149             }
150              
151             1;
152              
153             __END__