File Coverage

blib/lib/DBIx/MyParsePP/Rule.pm
Criterion Covered Total %
statement 89 103 86.4
branch 37 46 80.4
condition 11 15 73.3
subroutine 15 20 75.0
pod 0 14 0.0
total 152 198 76.7


line stmt bran cond sub pod time code
1             package DBIx::MyParsePP::Rule;
2             require Exporter;
3             @ISA = qw(Exporter);
4             @EXPORT = qw(MYPARSEPP_SHRINK_IDENTICAL MYPARSEPP_SHRINK_LEAFS MYPARSEPP_SHRINK_SINGLES MYPARSEPP_SHRINK_CHILDREN);
5              
6 6     6   42 use strict;
  6         15  
  6         216  
7              
8             1;
9              
10 6     6   36 use constant RULE_NAME => 0;
  6         12  
  6         407  
11              
12 6     6   30 use constant MYPARSEPP_SHRINK_IDENTICAL => 1;
  6         11  
  6         335  
13 6     6   29 use constant MYPARSEPP_SHRINK_LEAFS => 2;
  6         11  
  6         279  
14 6     6   29 use constant MYPARSEPP_SHRINK_SINGLES => 4;
  6         11  
  6         233  
15 6     6   30 use constant MYPARSEPP_SHRINK_CHILDREN => 8;
  6         17  
  6         13818  
16              
17             sub new {
18 26     26 0 39 my $class = shift;
19 26         66 my $rule = bless (\@_, $class);
20 26         60 return $rule;
21             }
22              
23             sub getName {
24 0     0 0 0 return $_[0]->[RULE_NAME];
25             }
26              
27             sub name {
28 1254     1254 0 3732 return $_[0]->[RULE_NAME];
29             }
30              
31             sub children {
32 10     10 0 17 my @rule = @{$_[0]};
  10         22  
33 10         42 return @rule[1..$#rule];
34             }
35              
36             sub getChildren {
37 0     0 0 0 my @rule = @{$_[0]};
  0         0  
38 0         0 return @rule[1..$#rule];
39             }
40              
41             sub toString {
42 50     50 0 1442 my $rule = shift;
43              
44 50 50       44 if ($#{$rule} > -1) {
  50         83  
45 72         180 return join('', map {
46 50         68 $rule->[$_]->toString();
47 50         52 } (1..$#{$rule}) );
48             } else {
49 0         0 return undef;
50             }
51             }
52              
53             sub shrink {
54 149     149 0 188 my ($parent, $flags) = @_;
55              
56 149 100       301 $flags = MYPARSEPP_SHRINK_IDENTICAL | MYPARSEPP_SHRINK_LEAFS | MYPARSEPP_SHRINK_SINGLES | MYPARSEPP_SHRINK_CHILDREN if not defined $flags;
57            
58 149 100 66     163 if (($#{$parent} == 0) && ($flags & MYPARSEPP_SHRINK_LEAFS)) {
  149 100 66     482  
  126 100       515  
59 23         40 return undef;
60             } elsif (($#{$parent} == 1) && ($flags & MYPARSEPP_SHRINK_SINGLES)) {
61 90 100       166 if ($flags & MYPARSEPP_SHRINK_CHILDREN) {
62 80         309 return $parent->[1]->shrink($flags);
63             } else {
64 10         45 return $parent->[1];
65             }
66             } elsif ($flags & MYPARSEPP_SHRINK_CHILDREN) {
67 24         31 my @new_children;
68              
69 24         26 foreach my $i (1..$#{$parent}) {
  24         70  
70 67         223 my $child = $parent->[$i]->shrink($flags);
71 67 50 66     364 if (
      66        
72             ($flags & MYPARSEPP_SHRINK_IDENTICAL) &&
73             (ref($child) eq 'DBIx::MyParsePP::Rule') &&
74             ($child->name() eq $parent->name())
75             ) {
76 0 0       0 push @new_children, $child->children() if defined $child->children();
77             } else {
78 67 100       192 push @new_children, $child if defined $child;
79             }
80             }
81              
82 24         61 my $new_rule = DBIx::MyParsePP::Rule->new($parent->name(), @new_children);
83 24         81 return $new_rule->shrink($flags & ~MYPARSEPP_SHRINK_CHILDREN);
84             } else {
85 12         43 return $parent;
86             }
87             }
88              
89              
90             sub extractInner {
91 522     522 0 500 my $rule = shift;
92 522 100       438 return undef if ($#{$rule} == 0);
  522         1157  
93              
94 400         499 my @matches;
95 400         357 foreach my $i (1..$#{$rule}) {
  400         613  
96 599         1427 my $extract = $rule->[$i]->extract(@_);
97 599 100       1089 next if not defined $extract;
98 365 100       611 if (ref($extract) eq 'ARRAY') {
99 78         75 push @matches, @{$extract};
  78         233  
100             } else {
101 287         495 push @matches, $extract;
102             }
103             }
104              
105 400 100       841 if ($#matches == -1) {
    100          
106 59         102 return undef;
107             } elsif ($#matches == 0) {
108 258         459 return $matches[0];
109             } else {
110 83         205 return \@matches;
111             }
112             }
113              
114             sub getFields {
115 1     1 0 5 return $_[0]->extract('simple_ident_q','table_ident','ident');
116             }
117              
118             sub fields {
119 0     0 0 0 return $_[0]->getFields();
120             }
121              
122             sub tables {
123 0     0 0 0 return $_[0]->getTables();
124             }
125              
126             sub getTables {
127 1     1 0 2 my $rule = shift;
128              
129 1         3 my @tables_array;
130             my %tables_hash;
131              
132 1         5 my $idents = $rule->extract('table_wild','table_ident','simple_ident_q');
133 1 50       6 $idents = [$idents] if ref($idents) ne 'ARRAY';
134            
135 1         1 foreach my $ident (@{$idents}) {
  1         3  
136 6         22 my $shrinked_ident = $ident->shrink();
137 6         18 my @children = $shrinked_ident->children();
138              
139 6         9 my $table;
140              
141 6 100       20 if ($#children == -1) { # No children
    50          
    100          
    50          
142 1         1 $table = $shrinked_ident;
143             } elsif ($#children == 0) { # One child
144 0         0 $table = $children[0];
145             } elsif ($#children == 2) {
146 3 100 100     6 if (
    50          
147             ($shrinked_ident->name() eq 'simple_ident_q') ||
148             ($shrinked_ident->name() eq 'table_wild')
149             ) {
150 2         3 $table = $children[0]; # We have "database.table"
151             } elsif ($shrinked_ident->name() eq 'table_ident') {
152 1         2 $table = $children[2]; # We have "table.field"
153             } else {
154 0         0 print STDERR "Assertion: \$\#children == $#children but name() = ".$shrinked_ident->name()."\n";
155 0         0 return undef;
156             }
157             } elsif ($#children == 4) { # We have "database.table.field"
158 2         5 $table = DBIx::MyParsePP::Rule->new( $ident->name(), @children[0..2] );
159             } else {
160 0         0 print STDERR "Assertion: \$\#children == $#children\n";
161 0         0 return undef;
162             }
163              
164 6 50       17 if (not exists $tables_hash{$table->toString()}) {
165 6         8 push @tables_array, $table;
166 6         14 $tables_hash{$table->toString()} = 1;
167             }
168             }
169              
170 1         6 return \@tables_array;
171            
172             }
173              
174             sub extract {
175 551     551 0 3342 my $rule = shift;
176 551         696 foreach my $match (@_) {
177 1193 100       1868 return $rule if ($rule->name() eq $match);
178             }
179 522         1215 return $rule->extractInner(@_);
180             }
181              
182             sub print {
183 0     0 0   return $_[0]->toString();
184             }
185              
186             1;
187              
188             __END__