File Coverage

blib/lib/MySQL/Hi.pm
Criterion Covered Total %
statement 63 94 67.0
branch 17 38 44.7
condition 5 14 35.7
subroutine 11 15 73.3
pod 6 7 85.7
total 102 168 60.7


line stmt bran cond sub pod time code
1             package MySQL::Hi;
2              
3 1     1   419768 use strict;
  1         3  
  1         47  
4 1     1   7 use warnings;
  1         2  
  1         129  
5              
6             our $VERSION = "1.04";
7              
8 1     1   9 use Carp;
  1         2  
  1         101  
9 1     1   7 use Config::Simple;
  1         3  
  1         11  
10              
11 1     1   771 use File::HomeDir;
  1         7743  
  1         1118  
12              
13             # Defaults
14             #
15             my %defaults = (
16             host => 'localhost',
17             port => 3306,
18             password => '',
19             );
20              
21              
22             # Constructor
23             #
24             # IN:
25             # %params = (
26             # user => 'john_doe',
27             # config => '/home/john_doe/mysqlhi.conf',
28             # );
29             #
30             sub new {
31 5     5 1 16702 my ( $class, %params ) = @_;
32              
33 5         21 my ( $user, $config ) = _parse_params( %params );
34 5         16 my $cred = _read_credentials( $config );
35              
36 5         97 my $self = bless {
37             _user => $user,
38             _config => $config,
39             _cred => $cred,
40             _options => {},
41             _dsn => {},
42             }, $class;
43              
44 5         18 return $self;
45             }
46              
47              
48             # Parse params
49             #
50             sub _parse_params {
51 5     5   14 my ( %params ) = @_;
52 5         14 my $user = delete $params{user};
53              
54 5 50       14 if ( defined $user ) {
55 0         0 $user =~ s/\s//g;
56 0 0       0 croak "Invalid user"
57             if length( $user ) == 0;
58             }
59             else {
60 5         11 $user = $ENV{USER};
61             }
62              
63             # Get config
64 5         11 my $config = delete $params{config};
65              
66 5 50 33     32 if ( !defined( $config ) || length( $config ) == 0 ) {
67 0         0 my $home = File::HomeDir->home();
68 0 0       0 if ( !$home ) {
69 0         0 croak "Cannot detect your home directory. You should explicitly specify the path to your config file\n";
70             }
71 0         0 $config = "$home/mysqlhi.conf";
72             }
73              
74 5 50       16 if ( my @keys = keys %params ) {
75 0         0 carp "Unknown constructor params: " . join(", ", @keys )
76             }
77              
78 5         16 return ( $user, $config );
79             }
80              
81              
82             # Makes sure that db name and mode are correct
83             #
84             sub _parse_db_mode {
85 19     19   29 my ( $db, $mode ) = @_;
86              
87             # DB name must exist
88 19 50 33     79 if ( !defined $db || $db =~ /^\s*$/ ) {
89 0         0 croak "No DB name provided";
90             }
91              
92 19         29 $db =~ s/^\s+//;
93 19         29 $db =~ s/\s+$//;
94              
95             # Empty or only spaces for $mode means no mode
96 19 50       34 if ( defined $mode ) {
97 0         0 $mode =~ s/^\s+//;
98 0         0 $mode =~ s/\s+$//;
99 0 0       0 if ( $mode =~ /^\s*$/ ) {
100 0         0 undef $mode;
101             }
102             }
103              
104             # Allowing $db to contain mode.
105 19   33     71 my $db_mode = join ':', $db, ( $mode // () );
106 19         39 my @db_mode = split ':', $db_mode, 2;
107 19         31 $db_mode = join ':', @db_mode;
108             return wantarray
109 19 50       46 ? ( $db_mode[0], $db_mode[1], $db_mode )
110             : $db_mode;
111             }
112              
113              
114             # Read credentials from the config file
115             #
116             sub _read_credentials {
117 5     5   9 my $config = shift;
118 5 50       106 if ( !-f $config ) {
119 0         0 croak "File '$config' does not exist\n";
120             }
121              
122 5         22 my $cfg = Config::Simple->new();
123 5 50       135 $cfg->read( $config )
124             or croak $cfg->error() . "\n";
125              
126 5         3567 my %cred = ();
127 5         117 my %vars = $cfg->vars();
128 5         894 for my $key ( keys %vars ) {
129 19 50       49 if ( $key !~ /\./ ) {
130 0         0 carp "Unknown parameter '$key' in config file, ignoring\n";
131 0         0 next;
132             }
133 19         46 my ( $db_mode, $param ) = split '\.', $key, 2;
134              
135 19         36 $db_mode = _parse_db_mode( $db_mode );
136              
137             # Fill in with default values
138 19 100       41 if ( !exists $cred{ $db_mode } ) {
139 9         25 for my $default ( keys %defaults ) {
140 27         58 $cred{ $db_mode }{ $default } = $defaults{ $default };
141             }
142             }
143              
144 19 100       37 unless ( exists $defaults{ $param } ) {
145 1         13 carp "Unknown parameter '$param' in [$db_mode]\n";
146 1         375 next;
147             }
148              
149 18         36 $cred{ $db_mode }{ $param } = $vars{ $key };
150             }
151              
152 5         28 return \%cred;
153             }
154              
155              
156             # Accessors
157             #
158             sub user {
159 0     0 1 0 return $_[0]->{_user};
160             }
161              
162             sub config {
163 0     0 1 0 return $_[0]->{_config};
164             }
165              
166             sub default_value {
167 9     9 0 34 my ( $self, $key ) = @_;
168             return exists $defaults{ $key }
169 9 50       27 ? $defaults{ $key }
170             : undef;
171             }
172              
173             # Return credentials for a specific DB and mode
174             #
175             sub get_credentials {
176 27     27 1 47372 my ( $self, $db, $mode ) = @_;
177              
178             return $self->{_cred}
179 27 50       78 if !$db;
180              
181 27   66     102 my $db_mode = join(':', $db, ($mode || () ) );
182              
183             return $self->{_cred}{ $db_mode }
184 27 100       80 if exists $self->{_cred}{ $db_mode };
185              
186 18         235 carp "No credentials for the '$db_mode' in config $self->{_config}\n";
187 18         6720 return \%defaults;
188             }
189              
190              
191             # Generates command line options for MySQL client
192             #
193             sub get_options {
194 0     0 1   my ( $self, $db, $mode ) = @_;
195              
196 0           ( $db, $mode, my $db_mode ) = _parse_db_mode( $db, $mode );
197              
198 0 0         if ( !exists $self->{_options}{ $db_mode } ) {
199 0           my $credentials = $self->get_credentials( $db, $mode );
200              
201             $self->{_options}{ $db_mode } = [
202             "-u" => $self->user(),
203             "-h" => $credentials->{host},
204             "-P" => $credentials->{port},
205 0           "-p$credentials->{password}",
206             "-D" => $db,
207             ];
208             }
209              
210 0           return @{ $self->{_options}{ $db_mode } };
  0            
211             }
212              
213              
214             # Generates DSN string for mysql driver
215             #
216             sub get_dsn {
217 0     0 1   my ( $self, $db, $mode ) = @_;
218              
219 0           ( $db, $mode, my $db_mode ) = _parse_db_mode( $db, $mode );
220              
221 0 0         if ( !exists $self->{_dsn}{ $db_mode } ) {
222 0           my $credentials = $self->get_credentials( $db, $mode );
223              
224             $self->{_dsn}{ $db_mode } = [
225             'DBI:mysql:'
226             . 'host=' . $credentials->{host}
227             . ';port=' . $credentials->{port}
228             . ';database=' . $db,
229             $self->user(),
230 0   0       $credentials->{password} // ''
231             ];
232             }
233              
234 0           return @{ $self->{_dsn}{ $db_mode } };
  0            
235             }
236              
237              
238              
239             1;
240              
241              
242             __END__