File Coverage

blib/lib/App/DoubleUp.pm
Criterion Covered Total %
statement 78 139 56.1
branch 6 14 42.8
condition 2 5 40.0
subroutine 22 29 75.8
pod 0 19 0.0
total 108 206 52.4


line stmt bran cond sub pod time code
1             package App::DoubleUp;
2 6     6   252343 use strict;
  6         17  
  6         240  
3 6     6   30 use warnings;
  6         9  
  6         262  
4             our $VERSION = '0.4.2';
5              
6 6     6   218 use 5.010;
  6         22  
  6         189  
7              
8              
9 6     6   30 use Carp;
  6         9  
  6         580  
10 6     6   28985 use DBI;
  6         172997  
  6         553  
11 6     6   6729 use YAML;
  6         96379  
  6         419  
12 6     6   25546 use File::Slurp;
  6         127579  
  6         568  
13 6     6   11799 use SQL::SplitStatement;
  6         247787  
  6         67  
14 6     6   15847 use File::Spec::Functions 'catfile';
  6         5865  
  6         553  
15 6     6   29723 use IO::Handle;
  6         55050  
  6         31511  
16              
17             sub new {
18 8     8 0 1872 my ($klass, $args) = @_;
19              
20 8         32 my $self = bless {}, $klass;
21              
22 8 100       46 if (!$args->{config_file}) {
23 3         17 for ('.', $ENV{HOME}) {
24 3         41 my $filename = catfile($_, '.doubleuprc');
25 3 50       109 if (-e $filename) {
26 3         11 $args->{config_file} = $filename;
27 3         10 last;
28             }
29             }
30             }
31 8         58 $self->{config_file} = $args->{config_file};
32              
33 8         50 $self->{config} = $self->load_config($self->config_file);
34              
35 8         164811 return $self;
36             }
37              
38             sub config_file {
39 10     10 0 32 my $self = shift;
40 10         61 return $self->{config_file};
41             }
42              
43             sub load_config {
44 8     8 0 25 my ($self, $filename) = @_;
45 8         55 return YAML::LoadFile($filename);
46             }
47              
48             sub source {
49 2     2 0 24 my ($self) = @_;
50 2         11 return $self->{config}{source};
51             }
52              
53             sub process_args {
54 4     4 0 49 my ($self, @args) = @_;
55              
56 4         20 $self->{command} = shift @args;
57              
58 4 100       37 if ($self->{command} eq 'import1') {
59 1         5 $self->{db} = [shift @args];
60 1         4 $self->{command} = 'import';
61             }
62              
63 4         18 $self->{files} = \@args;
64              
65 4         16 return;
66             }
67              
68             sub process_files {
69 0     0 0 0 my ($self, $files) = @_;
70              
71 0         0 my @querys;
72              
73 0         0 local $/ = ";\n";
74              
75 0         0 for my $filename (@$files) {
76 0         0 push @querys, $self->split_sql_file($filename);
77             }
78              
79 0         0 return @querys;
80             }
81             sub split_sql_file {
82 1     1 0 9 my ($self, $filename) = @_;
83 1         13 my $splitter = SQL::SplitStatement->new();
84 1         46 return $splitter->split(scalar read_file($filename));
85             }
86              
87             sub db_prepare {
88 0     0 0 0 my ($db, $query) = @_;
89 0         0 my $stmt = $db->prepare($query);
90 0         0 return $stmt;
91             }
92              
93             sub db_flatarray {
94 0     0 0 0 my ($db, $query, @args) = @_;
95 0         0 my $stmt = db_prepare($db, $query);
96 0         0 $stmt->execute(@args);
97 0         0 my @vals;
98 0         0 while (my $row = $stmt->fetchrow_arrayref) {
99 0         0 push @vals, $row->[0];
100             }
101 0         0 return @vals;
102             }
103              
104             sub list_of_schemata {
105 2     2 0 6 my ($self) = @_;
106 2         11 my $source = $self->source;
107 2 50       10 if ($source->{type} eq 'config') {
    0          
108 2         4 return @{ $source->{databases} };
  2         29  
109             }
110             elsif ($source->{type} eq 'database') {
111 0         0 my $db = $self->connect_to_db('dbi:mysql:information_schema', $self->credentials);
112 0         0 return db_flatarray($db, $source->{schemata_sql});
113             }
114             }
115              
116             sub credentials {
117 1     1 0 6 my $self = shift;
118 1         3 return @{$self->{config}{credentials}};
  1         12  
119             }
120              
121             sub connect_to_db {
122 0     0 0 0 my ($self, $dsn, $user, $password) = @_;
123 0   0     0 return DBI->connect($dsn, $user, $password, { RaiseError => 1, PrintError => 0 }) || croak "Error while connecting to '$dsn'";
124             }
125              
126             sub process_querys_for_one_db {
127 0     0 0 0 my ($self, $db, $querys) = @_;
128              
129 0         0 for my $q (@$querys) {
130 0 0       0 if ($self->process_one_query($db, $q)) {
131 0         0 print '.';
132             }
133             else {
134 0         0 print '!';
135             }
136             }
137 0         0 return;
138             }
139              
140             sub process_one_query {
141 0     0 0 0 my ($self, $db, $q) = @_;
142              
143 0         0 eval {
144 0         0 $db->do($q);
145             };
146 0 0       0 if ($@) {
147 0         0 return;
148             }
149 0         0 return 1;
150             }
151              
152             sub command {
153 5     5 0 23 my $self = shift;
154 5         37 return $self->{command};
155             }
156              
157             sub database_names {
158 3     3 0 9 my $self = shift;
159 3   100     53 $self->{db} //= [ $self->list_of_schemata ];
160 3         23 return $self->{db};
161             }
162              
163             sub files {
164 2     2 0 4 my $self = shift;
165 2         14 return $self->{files};
166             }
167              
168             sub run {
169 1     1 0 144 my ($self) = @_;
170              
171 1         13 STDOUT->autoflush(1);
172              
173 1         55 given ($self->command) {
174 1         10 when ('version') {
175 1         9 say "doubleup version $VERSION";
176             }
177 0         0 when ('listdb') {
178 0         0 my @db = $self->list_of_schemata();
179 0         0 for (@db) {
180 0         0 say;
181             }
182             }
183 0         0 when ('import') {
184 0         0 my @querys = $self->process_files($self->files);
185              
186 0         0 for my $schema (@{ $self->database_names }) {
  0         0  
187 0         0 my $dsn = 'dbi:mysql:'.$schema;
188 0         0 say "DB: $schema";
189 0         0 my $db = $self->connect_to_db($dsn, $self->credentials);
190 0         0 $self->process_querys_for_one_db($db, \@querys);
191 0         0 say '';
192             }
193             }
194 0         0 when (undef) {
195 0         0 $self->usage;
196             }
197 0         0 default {
198 0         0 say "Unknown command: $_";
199 0         0 $self->usage;
200             }
201             }
202 1         10 return;
203              
204             }
205             sub usage {
206 0     0 0   my $self = shift;
207 0           say "Usage: doubleup [command] [options]";
208 0           say "";
209 0           say "List of commands";
210 0           say "";
211 0           say " listdb list of schemata";
212 0           say " import [filename] import a file into each db";
213 0           say " import1 [db] [filename] import a file into one db";
214 0           say " version show version";
215 0           say "";
216 0           return;
217             }
218              
219             1;
220              
221             =head1 NAME
222              
223             App::DoubleApp - Import SQL files into MySQL
224              
225             =head1 SYNOPSIS
226              
227             $ doubleup listdb
228             ww_test1
229             ww_test2
230             ww_test3
231             ww_test4
232             $ doubleup import1 ww_test db/01_base.sql
233             .
234             $ doubleup import db/02_upgrade.sql
235             ....
236              
237             =head1 DESCRIPTION
238              
239             Import SQL files into a DBI compatible database.
240              
241             =head1 AUTHOR
242              
243             Peter Stuifzand Epeter@stuifzand.euE
244              
245             =head1 COPYRIGHT
246              
247             Copyright 2013- Peter Stuifzand
248              
249             =head1 LICENSE
250              
251             This library is free software; you can redistribute it and/or modify
252             it under the same terms as Perl itself.
253              
254             =head1 SEE ALSO
255              
256             =cut