File Coverage

lib/SQL/Admin/Catalog/Compare.pm
Criterion Covered Total %
statement 9 87 10.3
branch 0 34 0.0
condition 0 19 0.0
subroutine 3 14 21.4
pod 0 5 0.0
total 12 159 7.5


line stmt bran cond sub pod time code
1              
2             package SQL::Admin::Catalog::Compare;
3              
4 1     1   3135 use strict;
  1         3  
  1         52  
5 1     1   7 use warnings;
  1         3  
  1         63  
6              
7             our $VERSION = v0.5.0;
8              
9             ######################################################################
10              
11 1     1   1419 use Data::Compare;
  1         15013  
  1         8  
12              
13             ######################################################################
14              
15             our $HIDE_DROP_TABLE = 0;
16             our $HIDE_DROP_COLUMN = 0;
17             our $HIDE_DROP_SEQUENCE = 0;
18              
19             ######################################################################
20             ######################################################################
21             sub new { # ;
22 0     0 0   my ($class) = @_;
23              
24 0   0       bless [], ref $class || $class;
25             }
26              
27              
28             ######################################################################
29             ######################################################################
30             sub decompose { # ;
31 0     0 0   my ($self, $decomposer) = @_;
32 0           my @retval;
33              
34 0           for my $command (@$self) {
35 0 0         if ('HASH' eq ref $command) {
36 0           push @retval, $command;
37             } else {
38 0           my ($name, $catalog, $data) = @$command;
39              
40 0 0         push @retval, $decomposer->$name ($catalog, $data)
41             if $decomposer->can ($name);
42             }
43             }
44              
45 0           @retval;
46             }
47              
48              
49             ######################################################################
50             ######################################################################
51             sub _diff_schema { # ;
52 0     0     my ($self, $src, $dst) = @_;
53 0           my ($src_map, $dst_map) = map $_->list ('schema'), $src, $dst;
54              
55             push @$self, [ 'create_schema', $dst, $_ ]
56 0           for map $dst_map->{$_}, grep ! exists $src_map->{$_}, keys %$dst_map;
57             }
58              
59              
60             ######################################################################
61             ######################################################################
62             sub _diff_sequence { # ;
63 0     0     my ($self, $srccat, $dstcat) = @_;
64              
65 0   0       my $sseq = $srccat->list ('sequences') || {};
66 0   0       my $dseq = $dstcat->list ('sequences') || {};
67 0   0       my $dsc = $dstcat->{_schema} || {};
68              
69             # drop sequences
70             ##################################################################
71 0 0         unless ($HIDE_DROP_SEQUENCE) {
72             push @$self, [ drop_sequence => $srccat, $_ ]
73 0           for grep exists $dsc->{$_->{schema}},
74             map $sseq->{$_},
75             grep ! exists $dseq->{$_},
76             keys %$sseq;
77             }
78              
79             # create sequences
80             ##################################################################
81             push @$self, { create_sequence => $dstcat, $dseq->{$_} }
82 0           for grep ! exists $sseq->{$_}, # -- not in src
83             keys %$dseq; # ++ all dst sequences
84              
85             ##################################################################
86              
87 0           1;
88             }
89              
90              
91             ######################################################################
92             ######################################################################
93             sub _diff_table { # ;
94 0     0     my ($self, $srccat, $dstcat) = @_;
95              
96 0   0       my $stab = $srccat->list ('table') || {};
97 0   0       my $dtab = $dstcat->list ('table') || {};
98 0   0       my $dsc = $dstcat->{_schema} || {};
99              
100             # drop tables
101             ##################################################################
102 0 0         unless ($HIDE_DROP_TABLE) {
103             push @$self, [ 'drop_table', $srccat, $stab->{$_} ]
104 0           for grep exists $dsc->{$_->{schema}},
105             map $stab->{$_},
106             grep ! exists $dtab->{$_},
107             keys %$stab;
108             }
109              
110             # create tables
111             ##################################################################
112             push @$self, [ 'create_table', $dstcat, $dtab->{$_} ]
113 0           for grep ! exists $stab->{$_}, # -- not in src
114             keys %$dtab; # ++ all dst tables
115              
116             ##################################################################
117              
118 0           1;
119             }
120              
121              
122             ######################################################################
123             ######################################################################
124             sub _diff_column { # ;
125 0     0     my ($self, $srccat, $dstcat) = @_;
126 0           my $scol = $srccat->list ('column');
127 0           my $dcol = $dstcat->list ('column');
128 0           my $dtab = $dstcat->list ('table');
129 0           my $stab = $srccat->list ('table');
130              
131             # drop columns
132             ##################################################################
133 0 0         unless ($HIDE_DROP_COLUMN) {
134             push @$self, [ 'drop_column', $srccat, $scol->{$_} ]
135 0           for grep $stab->{$_->{table}{fullname}},
136             grep $dtab->{$_->{table}{fullname}},
137             map $scol->{$_},
138             grep ! $dcol->{$_},
139             keys %$scol;
140             }
141              
142             # add columns
143             ##################################################################
144 0           while (my ($key, $value) = each %$dcol) {
145 0 0         next if exists $scol->{$key};
146 0 0         next unless exists $stab->{ $value->table->fullname };
147 0 0         next unless exists $dtab->{ $value->table->fullname };
148              
149 0           push @$self, [ 'add_column', $dstcat, $value ];
150             }
151             }
152              
153              
154             ######################################################################
155             ######################################################################
156             sub _diff_column_not_null { # ;
157 0     0     my ($self, $srccat, $dstcat) = @_;
158 0           my $scol = $srccat->list ('column');
159 0           my $dcol = $dstcat->list ('column');
160 0           my $dtab = $dstcat->list ('table');
161 0           my $stab = $srccat->list ('table');
162              
163             ##################################################################
164 0           while (my ($key, $value) = each %$dcol) {
165             # alter only existing columns
166 0 0         next unless exists $scol->{$key};
167              
168 0 0 0       next if ($value->not_null || 0) == ($scol->{$key}->not_null || 0);
      0        
169              
170 0           push @$self, +{ alter_table => {
171             table_name => { name => $value->table->name, schema => $value->table->schema },
172             alter_table_actions => [ { alter_column => {
173             column_name => $value->name,
174             not_null => $value->not_null,
175             } } ] } };
176             }
177             }
178              
179              
180             ######################################################################
181             ######################################################################
182             sub _diff_column_default { # ;
183 0     0     my ($self, $srccat, $dstcat) = @_;
184 0           my $scol = $srccat->list ('column');
185 0           my $dcol = $dstcat->list ('column');
186 0           my $dtab = $dstcat->list ('table');
187 0           my $stab = $srccat->list ('table');
188              
189             ##################################################################
190 0           while (my ($key, $value) = each %$dcol) {
191             # alter only existing columns
192 0 0         next unless exists $scol->{$key};
193              
194 0 0         next if Data::Compare::Compare ($value->default, $scol->{$key}->default);
195              
196 0           push @$self, +{ alter_table => {
197             table_name => { name => $value->table->name, schema => $value->table->schema },
198             alter_table_actions => [ { alter_column => {
199             column_name => $value->name,
200             default_clause=> $value->default,
201             } } ] } };
202             }
203             }
204              
205              
206             ######################################################################
207             ######################################################################
208             sub compare { # ;
209 0     0 0   my ($self, $src, $dest) = @_;
210 0 0         $self = __PACKAGE__->new unless ref $self;
211              
212 0           @$self = ();
213              
214 0           $self->_diff_schema ($src, $dest);
215 0           $self->_diff_table ($src, $dest);
216             # $self->_diff_sequence ($src, $dest);
217             # $self->_diff_index ($src, $dest);
218             # # $self->_diff_view ($src, $dest);
219             # # $self->_diff_trigger ($src, $dest);
220             # # $self->_diff_function ($src, $dest);
221 0           $self->_diff_column ($src, $dest);
222             # {
223 0           $self->_diff_column_not_null ($src, $dest);
224 0           $self->_diff_column_default ($src, $dest);
225             # $self->_diff_constraints ($src, $dest);
226             # }
227              
228 0           $self;
229             }
230              
231              
232             ######################################################################
233             ######################################################################
234             sub is_difference { # ;
235 0     0 0   my $self= shift;
236              
237 0           return @$self > 0;
238             }
239              
240              
241             ######################################################################
242             ######################################################################
243             sub save { # ;
244 0     0 0   my ($self, $driver, @params) = @_;
245              
246 0 0         $driver = SQL::Admin->get_driver ($driver, @{ shift @params || [] } )
  0 0          
247             unless ref $driver;
248              
249 0           my @list = $self->decompose ($driver->decomposer);
250              
251             ##################################################################
252              
253 0           my $fh = \*STDOUT;
254 0 0         if ($driver->{file}) {
255 0 0         open $fh, '>', $driver->{file}
256             or die "Unable write to $driver->{file}: $!\n";
257             }
258              
259 0           print $fh $driver->producer->produce (@list);
260             }
261              
262              
263             ######################################################################
264             ######################################################################
265              
266             package SQL::Admin::Catalog::Compare;
267              
268             1;
269              
270             __END__