File Coverage

blib/lib/MySQL/Util/CLI.pm
Criterion Covered Total %
statement 156 450 34.6
branch 0 168 0.0
condition 0 42 0.0
subroutine 52 72 72.2
pod n/a
total 208 732 28.4


line stmt bran cond sub pod time code
1             package MySQL::Util::CLI;
2             $MySQL::Util::CLI::VERSION = '0.001';
3             =head1 NAME
4              
5             MySQL::Util::CLI
6              
7             =head1 VERSION
8              
9             version 0.001
10              
11             =cut
12              
13 2     2   325684 use Modern::Perl;
  2         16  
  2         19  
14 2     2   1558 use Moose;
  2         942887  
  2         15  
15 2     2   17172 use namespace::autoclean;
  2         17373  
  2         7  
16 2     2   1129 use Kavorka '-all';
  2         21726  
  2         17  
17 2     2   760923 use MySQL::Util;
  2         656699  
  2         108  
18 2     2   22 use Carp;
  2         5  
  2         174  
19 2     2   16 use Data::Printer alias => 'pdump';
  2         13  
  2         22  
20              
21             with 'Util::Medley::Roles::Attributes::Logger';
22             with 'Util::Medley::Roles::Attributes::String';
23              
24 2     2   2748 use constant DEFAULT_USER => 'root';
  2         5  
  2         179  
25 2     2   12 use constant DEFAULT_PORT => 3306;
  2         4  
  2         95  
26 2     2   16 use constant DEFAULT_HOST => 'localhost';
  2         5  
  2         98  
27 2     2   14 use constant DEFAULT_DBNAME => 'mysql';
  2         4  
  2         347  
28              
29             ##################################################################
30              
31             # MYSQL_USER, DBI_USER, USER, DEFAULT_USER
32             has user => (
33             is => 'rw',
34             isa => 'Str',
35             lazy => 1,
36             builder => '_buildUser',
37             );
38              
39             # MYSQL_PASS, MYSQL_PWD, or confess
40             has pass => (
41             is => 'rw',
42             isa => 'Str',
43             lazy => 1,
44             builder => '_buildPass',
45             );
46              
47             # MYSQL_HOST or DEFAULT_HOST
48             has host => (
49             is => 'rw',
50             isa => 'Str',
51             lazy => 1,
52             builder => '_buildHost',
53             );
54              
55             # MYSQL_PORT, MYSQL_TCP_PORT, or DEFAULT_PORT
56             has port => (
57             is => 'rw',
58             isa => 'Str',
59             lazy => 1,
60             builder => '_buildPort',
61             );
62              
63             # MYSQL_DBNAME, MYSQL_SCHEMA, or DEFAULT_DBNAME
64             has dbName => (
65             is => 'rw',
66             isa => 'Str',
67             lazy => 1,
68             builder => '_buildDbName',
69             );
70              
71             has raiseError => (
72             is => 'ro',
73             isa => 'Int',
74             default => 1,
75             );
76              
77             has printError => (
78             is => 'ro',
79             isa => 'Int',
80             default => 0,
81             );
82              
83             has fetchHashKeyName => (
84             is => 'ro',
85             isa => 'Str',
86             default => 'NAME_lc',
87             );
88              
89             has dryRun => (
90             is => 'ro',
91             isa => 'Bool',
92             default => 0,
93             );
94              
95             ##################################################################
96              
97             has _util => (
98             is => 'rw',
99             isa => 'MySQL::Util',
100             lazy => 1,
101             builder => '_buildUtil',
102             );
103              
104             has _dbh => (
105             is => 'rw',
106             lazy => 1,
107             builder => '_buildDbh',
108             );
109              
110             ##################################################################
111              
112             #
113             # drop all anonymous user entries
114             # * dropUser(userName => '')
115             #
116             # drop all user foo entries
117             # * dropUser(userName => 'foo')
118             #
119             # drop all root entries except '%'
120             # * dropUser(userName => 'root', keepHosts => ['%'])
121             #
122             method dropUser (Str :$userName!,
123             Str :$hosts,
124 2 0 0 2   67569 ArrayRef[Str] :$keepHosts) {
  2 0 0 2   5  
  2 0   2   265  
  2 0   2   28  
  2 0   0   5  
  2 0       111  
  2 0       1102  
  2 0       2981  
  2 0       12  
  2         197  
  2         7  
  2         1839  
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
125              
126 0           my @sql = ('select * from user');
127 0           my @where = ('user = ?');
128 0           my @bind = ($userName);
129              
130 0 0         if ($hosts) {
    0          
131 0           foreach my $host (@$hosts) {
132 0           push @where, 'host = ?';
133 0           push @bind, $hosts;
134             }
135             }
136             elsif ($keepHosts) {
137 0           foreach my $keepHost (@$keepHosts) {
138 0           push @where, 'host != ?';
139 0           push @bind, $keepHost;
140             }
141             }
142              
143 0           push @sql, 'where', join(' and '), @where;
144 0           my $sql = join ' ', @sql;
145              
146 0           $self->Logger->verbose( sprintf 'bind vars: (%s)', join( ', ', @bind ) );
147 0           $self->Logger->verbose($sql);
148              
149 0           my $dbh = $self->getDbh;
150 0           my $sth = $dbh->prepare($sql);
151 0           $sth->execute(@bind);
152              
153 0           while ( my $href = $sth->fetchrow_hashref ) {
154              
155 0           my $sql = sprintf q{drop user '%s'@'%s'}, $userName, $href->{host};
156 0           $self->doSql( sql => $sql );
157             }
158              
159 0           $self->flushPrivileges;
160             }
161              
162             method createDatabase (Str :$dbName!,
163 2 0 0 2   7331 Bool :$ifNotExists = 1) {
  2 0 0 2   6  
  2 0   2   255  
  2 0   2   15  
  2 0   0   4  
  2 0       100  
  2         14  
  2         3  
  2         9  
  2         152  
  2         4  
  2         1053  
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
164              
165 0           my @sql = 'create database';
166 0 0         push @sql, "if not exists" if $ifNotExists;
167 0           push @sql, $dbName;
168            
169 0           $self->doSql( sql => join(' ', @sql));
170             }
171              
172             method getGrants (Str :$forUser,
173 2 0 0 2   7361 Str :$forHost) {
  2 0 0 2   5  
  2 0   2   242  
  2 0   2   15  
  2 0   0   5  
  2 0       97  
  2 0       16  
  2         4  
  2         25  
  2         141  
  2         5  
  2         1238  
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
174              
175 0           my @sql = 'show grants';
176 0 0         if ($forUser) {
177 0           push @sql, "for";
178 0           push @sql, "'$forUser'";
179 0 0         push @sql, sprintf( "%s'%s'", '@', $forHost) if $forHost;
180             }
181              
182 0           my $dbh = $self->getDbh;
183 0           my $sql = join(' ', @sql);
184 0           $self->Logger->verbose($sql);
185 0           my $aref = $dbh->selectall_arrayref($sql);
186            
187 0           return @$aref;
188             }
189              
190             method userExists (Str :$userName!,
191 2 0 0 2   6127 Str :$host!) {
  2 0 0 2   6  
  2 0   2   232  
  2 0   2   15  
  2 0   0   4  
  2 0       100  
  2 0       14  
  2         4  
  2         8  
  2         148  
  2         4  
  2         1180  
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
192 0           my $sql = q{
193             select
194             *
195             from
196             user
197             where
198             user = ? and
199             host = ?
200             };
201              
202 0           my $aref =
203             $self->getDbh->selectrow_arrayref( $sql, undef, $userName, $host );
204              
205 0 0         if ($aref) {
206 0           $self->Logger->verbose("user exists");
207 0           return 1;
208             }
209              
210 0           return 0;
211             }
212              
213             method grantPrivileges (Str :$userName!,
214             ArrayRef[Str] :$hosts = [DEFAULT_HOST],
215             ArrayRef[Str] :$privileges!,
216             Str :$dbName = '*',
217 2 0 0 2   16086 Str :$tables = '*') {
  2 0 0 2   5  
  2 0   2   222  
  2 0   2   16  
  2 0   0   4  
  2 0       111  
  2 0       16  
  2 0       4  
  2 0       10  
  2 0       198  
  2         12  
  2         1539  
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
218              
219 0           foreach my $host (@$hosts) {
220              
221 0           my @sql = ('grant');
222 0           push @sql, join( ', ', @$privileges );
223 0           push @sql, 'on';
224 0           push @sql, sprintf( '%s.%s', $dbName, $tables );
225 0           push @sql, 'to';
226 0           push @sql, sprintf( '%s@%s', $userName, $host );
227              
228 0           $self->doSql( sql => join( ' ', @sql ) );
229             }
230              
231 0           $self->flushPrivileges;
232             }
233              
234             method createUser (Str :$userName!,
235             Str :$userPass!,
236 2 0 0 2   9852 ArrayRef[Str] :$hosts = []) {
  2 0 0 2   4  
  2 0   2   234  
  2 0   2   15  
  2 0   0   4  
  2 0       100  
  2 0       14  
  2 0       3  
  2         10  
  2         178  
  2         4  
  2         1342  
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
237              
238 0           foreach my $host (@$hosts) {
239 0 0         if ( !$self->userExists( userName => $userName, host => $host ) ) {
240 0           my $sql = sprintf "create user '%s'\@'%s' identified by '%s'",
241             $userName,
242             $host, $userPass;
243              
244 0           $self->doSql( sql => $sql, );
245             }
246             }
247              
248 0           $self->flushPrivileges;
249             }
250              
251 2 0   2   2312 method getMysqlCli {
  2     0   5  
  2         380  
  0            
  0            
252              
253 0           my @cmd = ('mysql');
254 0           push @cmd, '-u', $self->user;
255 0           push @cmd, sprintf '--password="%s"', $self->pass; # is there a better way?
256 0           push @cmd, '-h', $self->host;
257 0           push @cmd, '-P', $self->port;
258 0           push @cmd, '-D', $self->dbName;
259              
260 0           return join( ' ', @cmd );
261             }
262              
263 2 0   2   2263 method printMysqlCli {
  2     0   6  
  2         200  
  0            
  0            
264              
265 0           say $self->getMysqlCli;
266             }
267              
268             method doSql (Str :$sql!,
269 2 0 0 2   6840 ArrayRef :$bind = []) {
  2 0 0 2   5  
  2 0   2   220  
  2 0   2   15  
  2 0   0   4  
  2 0       90  
  2         14  
  2         4  
  2         18  
  2         156  
  2         4  
  2         1197  
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
270              
271 0           my $dbh = $self->getDbh;
272              
273 0           $sql = $self->String->trim($sql);
274              
275 0           $self->Logger->verbose( sprintf 'bind vars: (%s)', join( ', ', @$bind ) );
276 0           $self->Logger->verbose($sql);
277              
278 0 0         if ( !$self->dryRun ) {
279 0           $dbh->do( $sql, undef, @$bind );
280             }
281             }
282              
283 2 0   2   2399 method flushPrivileges {
  2     0   4  
  2         172  
  0            
  0            
284              
285 0           $self->doSql( sql => "flush privileges" );
286             }
287              
288 2 0   2   2330 method getMysqlUtil {
  2     0   5  
  2         188  
  0            
  0            
289              
290 0           return $self->_util;
291             }
292              
293 2 0   2   2233 method getDbh {
  2     0   5  
  2         203  
  0            
  0            
294              
295 0           return $self->_dbh;
296             }
297              
298             ##################################################################
299              
300 2 0   2   2385 method _buildUser {
  2     0   5  
  2         359  
  0            
  0            
301              
302 0 0         return $ENV{MYSQL_USER} if $ENV{MYSQL_USER};
303 0 0         return $ENV{DBI_USER} if $ENV{DBI_USER};
304 0 0         return $ENV{USER} if $ENV{USER};
305 0           return DEFAULT_USER;
306             }
307              
308 2 0   2   2265 method _buildPass {
  2     0   4  
  2         276  
  0            
  0            
309              
310 0 0         return $ENV{MYSQL_PASS} if $ENV{MYSQL_PASS};
311 0 0         return $ENV{MYSQL_PWD} if $ENV{MYSQL_PWD};
312 0           confess "unable to derive a password";
313             }
314              
315 2 0   2   2248 method _buildHost {
  2     0   5  
  2         259  
  0            
  0            
316              
317 0 0         return $ENV{MYSQL_HOST} if $ENV{MYSQL_HOST};
318 0           return DEFAULT_HOST;
319             }
320              
321 2 0   2   2369 method _buildPort {
  2     0   4  
  2         310  
  0            
  0            
322              
323 0 0         return $ENV{MYSQL_PORT} if $ENV{MYSQL_PORT};
324 0 0         return $ENV{MYSQL_TCP_PORT} if $ENV{MYSQL_TCP_PORT};
325 0           return DEFAULT_PORT;
326             }
327              
328 2 0   2   2272 method _buildDbName {
  2     0   6  
  2         318  
  0            
  0            
329              
330 0 0         return $ENV{MYSQL_DBNAME} if $ENV{MYSQL_DBNAME};
331 0 0         return $ENV{MYSQL_SCHEMA} if $ENV{MYSQL_SCHEMA};
332 0           return DEFAULT_DBNAME;
333             }
334              
335 2 0   2   2198 method _getNewDbh {
  2     0   5  
  2         477  
  0            
  0            
336              
337 0           my @dsn = sprintf 'dbi:mysql:host=%s', $self->host;
338 0           push @dsn, sprintf 'database=%s', $self->dbName;
339 0           push @dsn, sprintf 'port=%s', $self->port;
340 0           my $dsn = join ';', @dsn;
341              
342 0           my $dbh = DBI->connect(
343             $dsn,
344             $self->user,
345             $self->pass,
346             {
347             RaiseError => $self->raiseError,
348             PrintError => $self->printError,
349             }
350             );
351              
352 0           $self->Logger->verbose( "connected to $dsn as " . $self->user );
353              
354 0           return $dbh;
355             }
356              
357 2 0   2   2495 method _buildDbh {
  2     0   6  
  2         274  
  0            
  0            
358              
359 0           my $dbh = $self->_getNewDbh;
360 0           $dbh->{FetchHashKeyName} = $self->fetchHashKeyName;
361              
362 0           return $dbh;
363             }
364              
365 2 0   2   2326 method _buildUtil {
  2     0   4  
  2         297  
  0            
  0            
366              
367 0           return MySQL::Util->new( dbh => $self->_getNewDbh );
368             }
369              
370             1;