File Coverage

blib/lib/Data/Generator/FromDDL/Director.pm
Criterion Covered Total %
statement 78 82 95.1
branch 15 22 68.1
condition n/a
subroutine 16 17 94.1
pod 0 2 0.0
total 109 123 88.6


line stmt bran cond sub pod time code
1             package Data::Generator::FromDDL::Director;
2 6     6   35 use strict;
  6         10  
  6         202  
3 6     6   32 use warnings;
  6         13  
  6         207  
4 6     6   30 use Carp qw(croak);
  6         19  
  6         447  
5 6     6   33 use List::MoreUtils qw(any);
  6         11  
  6         547  
6             use Class::Accessor::Lite (
7 6         47 new => 1,
8             rw => [qw(builder_class schema include exclude)],
9 6     6   34 );
  6         29  
10              
11 6     6   4464 use Data::Generator::FromDDL::Formatter;
  6         21  
  6         5238  
12              
13             sub generate {
14 20     20 0 56 my ($self, $num, $format, $pretty, $bytes_per_sql) = @_;
15 20         138 my @tables = $self->_get_right_order_tables;
16 20 50       92 croak("Not all tables found: You must specify all tables schema.\n")
17             unless @tables;
18              
19 20         41 my @recordsets;
20 20         52 for my $table (@tables) {
21 21         101 my $builder = $self->builder_class->new({
22             table => $table,
23             recordsets => \@recordsets,
24             });
25 21         1193 my $n = $self->_get_num_for_table($num, $table->name);
26              
27 21 50       164 if ($n) {
28 21         187 push @recordsets, $builder->generate($n);
29             }
30             }
31              
32 20         143 return @recordsets;
33             }
34              
35             sub flush {
36 20     20 0 61 my ($self, $recordsets, $out_fh, $format, $pretty, $bytes_per_sql) = @_;
37              
38 20         219 my $formatter = Data::Generator::FromDDL::Formatter->new(
39             format => $format,
40             pretty => $pretty,
41             bytes_per_sql => $bytes_per_sql,
42             );
43              
44 20         274 for my $recordset (@$recordsets) {
45             $recordset->iterate_through_chunks(sub {
46 21     21   51 my ($table, $fields, $rows) = @_;
47 21         159 my $sql = $formatter->to_string($table, $fields, $rows);
48 21         1181 print $out_fh $sql . "\n";
49 21         249 });
50             }
51             }
52              
53             sub _get_num_for_table {
54 21     21   2055 my ($self, $num, $table_name) = @_;
55 21 100       104 if (ref $num eq 'HASH') {
56 1 50       7 return exists $num->{tables}{$table_name}
57             ? $num->{tables}{$table_name}
58             : $num->{all};
59             } else {
60 20         51 return $num;
61             }
62             }
63              
64             sub _get_right_order_tables {
65 20     20   42 my $self = shift;
66 20         110 my @tables = $self->schema->get_tables;
67 20         1774 my @filtered = $self->_filter_tables(\@tables);
68              
69 20         77 return $self->_resolve_data_generation_order(\@filtered);
70             }
71              
72             sub _filter_tables {
73 20     20   53 my ($self, $tables) = @_;
74 20         48 my @include = @{$self->include};
  20         1211  
75 20         124 my @exclude = @{$self->exclude};
  20         92  
76              
77 20         118 my @filtered;
78 20 100       117 if (scalar(@include)) {
    50          
79 1         3 for my $t (@$tables) {
80 2 100   2   153 push @filtered, $t if any { $t->name eq $_ } @include;
  2         61  
81             }
82             } elsif (scalar(@exclude)) {
83 0         0 for my $t (@$tables) {
84 0 0   0   0 push @filtered, $t unless any { $t->name eq $_ } @exclude;
  0         0  
85             }
86             } else {
87 19         56 @filtered = @$tables;
88             }
89              
90 20         155 return @filtered;
91             }
92              
93             sub _resolve_data_generation_order {
94 20     20   46 my ($self, $tables) = @_;
95 20         52 my @unresolved = @$tables;
96 20         37 my @resolved;
97              
98 20         101 while (my @before = @unresolved) {
99 21         90 $self->_resolve_inter_table_reference(\@unresolved, \@resolved);
100              
101             # can't resolve inter table reference anymore.
102 21 50       133 if (@before == @unresolved) {
103 0         0 croak("Not all tables found: You must specify all tables schema.\n");
104             }
105             }
106              
107 20         71 return @resolved;
108             }
109              
110             sub _resolve_inter_table_reference {
111 21     21   51 my ($self, $unresolved, $resolved) = @_;
112 21         51 my @old_unresolved = @$unresolved;
113 21         77 splice @$unresolved, 0;
114              
115 21         49 for my $ur (@old_unresolved) {
116 22 100       72 if ($self->_exist_all_foreign_key_reference($ur, $resolved)) {
117 21         91 push @$resolved, $ur;
118             } else {
119 1         3 push @$unresolved, $ur;
120             }
121             }
122             }
123              
124             sub _exist_all_foreign_key_reference {
125 22     22   45 my ($self, $table, $others) = @_;
126 22         92 my @fk_constraints = grep { uc($_->type) eq 'FOREIGN KEY' }
  6         422  
127             $table->get_constraints;
128 22         1521 for my $constraint (@fk_constraints) {
129 2         6 my $ref_table = $constraint->reference_table;
130 2 100       8 unless (grep { $ref_table eq $_->name } @$others) {
  1         21  
131 1         7 return undef;
132             }
133             }
134              
135 21         160 return 1;
136             }
137              
138             1;