File Coverage

blib/lib/DBIx/MyParsePP/Rule.pm
Criterion Covered Total %
statement 97 111 87.3
branch 43 54 79.6
condition 11 15 73.3
subroutine 16 21 76.1
pod 0 15 0.0
total 167 216 77.3


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 8     8   44 use strict;
  8         14  
  8         219  
7              
8             1;
9              
10 8     8   36 use constant RULE_NAME => 0;
  8         13  
  8         491  
11              
12 8     8   36 use constant MYPARSEPP_SHRINK_IDENTICAL => 1;
  8         14  
  8         278  
13 8     8   35 use constant MYPARSEPP_SHRINK_LEAFS => 2;
  8         13  
  8         277  
14 8     8   36 use constant MYPARSEPP_SHRINK_SINGLES => 4;
  8         12  
  8         287  
15 8     8   38 use constant MYPARSEPP_SHRINK_CHILDREN => 8;
  8         38  
  8         8573  
16              
17             sub new {
18 87     87 0 99 my $class = shift;
19 87         127 my $rule = bless (\@_, $class);
20 87         146 return $rule;
21             }
22              
23             sub getName {
24 0     0 0 0 return $_[0]->[RULE_NAME];
25             }
26              
27             sub name {
28 1587     1587 0 3154 return $_[0]->[RULE_NAME];
29             }
30              
31             sub children {
32 222     222 0 227 my @rule = @{$_[0]};
  222         321  
33 222         388 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 770 my $rule = shift;
43              
44 50 50       48 if ($#{$rule} > -1) {
  50         79  
45             return join('', map {
46 72         122 $rule->[$_]->toString();
47 50         55 } (1..$#{$rule}) );
  50         59  
48             } else {
49 0         0 return undef;
50             }
51             }
52              
53             sub shrink {
54 545     545 0 992 my ($parent, $flags) = @_;
55              
56 545 100       769 $flags = MYPARSEPP_SHRINK_IDENTICAL | MYPARSEPP_SHRINK_LEAFS | MYPARSEPP_SHRINK_SINGLES | MYPARSEPP_SHRINK_CHILDREN if not defined $flags;
57            
58 545 100 66     509 if (($#{$parent} == 0) && ($flags & MYPARSEPP_SHRINK_LEAFS)) {
  545 100 66     1022  
    100          
59 111         155 return undef;
60 434         919 } elsif (($#{$parent} == 1) && ($flags & MYPARSEPP_SHRINK_SINGLES)) {
61 308 100       402 if ($flags & MYPARSEPP_SHRINK_CHILDREN) {
62 266         512 return $parent->[1]->shrink($flags);
63             } else {
64 42         114 return $parent->[1];
65             }
66             } elsif ($flags & MYPARSEPP_SHRINK_CHILDREN) {
67 85         89 my @new_children;
68              
69 85         94 foreach my $i (1..$#{$parent}) {
  85         137  
70 271         499 my $child = $parent->[$i]->shrink($flags);
71 271 50 66     721 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 271 100       538 push @new_children, $child if defined $child;
79             }
80             }
81              
82 85         125 my $new_rule = DBIx::MyParsePP::Rule->new($parent->name(), @new_children);
83 85         160 return $new_rule->shrink($flags & ~MYPARSEPP_SHRINK_CHILDREN);
84             } else {
85 41         91 return $parent;
86             }
87             }
88              
89              
90             sub extractInner {
91 522     522 0 542 my $rule = shift;
92 522 100       502 return undef if ($#{$rule} == 0);
  522         798  
93              
94 400         431 my @matches;
95 400         403 foreach my $i (1..$#{$rule}) {
  400         533  
96 599         992 my $extract = $rule->[$i]->extract(@_);
97 599 100       839 next if not defined $extract;
98 365 100       497 if (ref($extract) eq 'ARRAY') {
99 78         76 push @matches, @{$extract};
  78         144  
100             } else {
101 287         401 push @matches, $extract;
102             }
103             }
104              
105 400 100       609 if ($#matches == -1) {
    100          
106 59         83 return undef;
107             } elsif ($#matches == 0) {
108 258         363 return $matches[0];
109             } else {
110 83         132 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 3 my $rule = shift;
128              
129 1         2 my @tables_array;
130             my %tables_hash;
131              
132 1         3 my $idents = $rule->extract('table_wild','table_ident','simple_ident_q');
133 1 50       4 $idents = [$idents] if ref($idents) ne 'ARRAY';
134            
135 1         2 foreach my $ident (@{$idents}) {
  1         3  
136 6         12 my $shrinked_ident = $ident->shrink();
137 6         11 my @children = $shrinked_ident->children();
138              
139 6         8 my $table;
140              
141 6 100       18 if ($#children == -1) { # No children
    50          
    100          
    50          
142 1         2 $table = $shrinked_ident;
143             } elsif ($#children == 0) { # One child
144 0         0 $table = $children[0];
145             } elsif ($#children == 2) {
146 3 100 100     4 if (
    50          
147             ($shrinked_ident->name() eq 'simple_ident_q') ||
148             ($shrinked_ident->name() eq 'table_wild')
149             ) {
150 2         4 $table = $children[0]; # We have "database.table"
151             } elsif ($shrinked_ident->name() eq 'table_ident') {
152 1         3 $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         3 $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       11 if (not exists $tables_hash{$table->toString()}) {
165 6         8 push @tables_array, $table;
166 6         11 $tables_hash{$table->toString()} = 1;
167             }
168             }
169              
170 1         6 return \@tables_array;
171            
172             }
173              
174             sub extract {
175 551     551 0 1788 my $rule = shift;
176 551         638 foreach my $match (@_) {
177 1193 100       1363 return $rule if ($rule->name() eq $match);
178             }
179 522         806 return $rule->extractInner(@_);
180             }
181              
182             sub print {
183 0     0 0 0 return $_[0]->toString();
184             }
185              
186             sub isEqual {
187 107 50   107 0 207 return 0 if !$_[1]->isa( 'DBIx::MyParsePP::Rule' );
188 107 100       140 return 0 if $_[0]->name() ne $_[1]->name();
189              
190 106         151 my @left_children = $_[0]->children();
191 106         158 my @right_children = $_[1]->children();
192 106 50       156 return 0 if @left_children != @right_children;
193              
194 106         172 for( my $i = 0; $i < @left_children; $i++ ) {
195 149 100       283 return 0 if !$left_children[$i]->isEqual( $right_children[$i] );
196             }
197              
198 105         211 return 1;
199             }
200              
201             1;
202              
203             __END__