File Coverage

blib/lib/Data/Presenter/Combo/Union.pm
Criterion Covered Total %
statement 83 83 100.0
branch 8 8 100.0
condition n/a
subroutine 7 7 100.0
pod n/a
total 98 98 100.0


line stmt bran cond sub pod time code
1             package Data::Presenter::Combo::Union;
2             #$Id: Union.pm 1218 2008-02-10 00:11:59Z jimk $
3             $VERSION = 1.03; # 02-10-2008
4             @ISA = qw(Data::Presenter::Combo);
5 1     1   1830 use strict;
  1         1  
  1         35  
6 1     1   5 use warnings;
  1         2  
  1         32  
7 1     1   5 use Data::Dumper;
  1         1  
  1         836  
8              
9             our %reserved_partial = (
10             'fields' => 1,
11             'index' => 1,
12             'options' => 1,
13             );
14              
15             sub _merge_engine {
16 2     2   4 my ($self, $mergeref) = @_;
17              
18 2         3 my %base = %{${$mergeref}{base}};
  2         3  
  2         20  
19 2         6 my %sec = %{${$mergeref}{secondary}};
  2         15  
  2         14  
20 2         5 my %newbase = %{${$mergeref}{newbase}};
  2         2  
  2         7  
21 2         4 my %secneeded = %{${$mergeref}{secfieldsneeded}};
  2         2  
  2         7  
22 2         6 my %sharedfields = %{${$mergeref}{sharedfields}};
  2         2  
  2         42  
23            
24 2         5 my @basefields = @{$base{'fields'}};
  2         8  
25 2         4 my %seen = ();
26              
27             # Build 2 look-up tables showing records found in base and sec
28 2         7 my %seenbase = _build_lookup_table(\%base);
29 2         10 my %seensec = _build_lookup_table(\%sec);
30              
31             # Build 3 look-up tables showing whether fields were found in
32             # base only, sec only, or both
33             # (At a future date, consider replacing with List::Compare methods)
34 2         8 my %seenbaseonly = ();
35 2         4 my %seenseconly = ();
36 2         3 my %seenboth = ();
37 2         26 foreach my $rec (keys %seenbase) {
38 30 100       53 if (defined $seensec{$rec}) {
39 12         19 $seenboth{$rec} = 1;
40             } else {
41 18         31 $seenbaseonly{$rec} = 1;
42             }
43             }
44 2         9 foreach my $rec (keys %seensec) {
45 20 100       43 $seenseconly{$rec} = 1
46             unless ($seenboth{$rec});
47             }
48              
49             # Work thru the 3 look-up tables to assign values
50 2         7 my $null = q{};
51 2         13 foreach my $rec (keys %seenbaseonly) {
52 18         38 my @values = _process_base(\%base, $rec);
53            
54             # If an individual record was only found in the base, then, by
55             # definition, its 'entries' in the sec are all 'null'.
56             # We only need to assign as many nulls as there are keys in
57             # %secneeded.
58 18         50 for (my $p=0; $p < scalar(keys %secneeded); $p++) {
59 44         89 push(@values, $null);
60             }
61 18         82 $newbase{$rec} = [@values];
62             }
63 2         7 foreach my $rec (keys %seenseconly) {
64 8         11 my @values;
65 8         20 for (my $q=0; $q < scalar(@basefields); $q++) {
66 62         69 my $bf = $basefields[$q];
67 62 100       160 if ($sharedfields{$bf}) {
68 24         80 $values[$q] = $sec{$rec}->[$sharedfields{$bf}[1]];
69             } else {
70 38         89 $values[$q] = $null;
71             }
72             }
73 8         21 @values = _process_secneeded(\%secneeded, \%sec, $rec, \@values);
74 8         49 $newbase{$rec} = [@values];
75             }
76 2         17 foreach my $rec (keys %seenboth) {
77             # If a field is seen in both base and sec, we follow a rule that says
78             # the base-value for that field gets assigned to the union -- not the
79             # sec-value.
80 12         24 my @values = _process_base(\%base, $rec);
81 12         28 @values = _process_secneeded(\%secneeded, \%sec, $rec, \@values);
82 12         61 $newbase{$rec} = [@values];
83             }
84 2         24 return \%newbase;
85             }
86              
87             sub _build_lookup_table {
88 4     4   8 my $dataref = shift;
89 4         5 my %lookup;
90 4         6 foreach my $rec (keys %{$dataref}) {
  4         22  
91 58 100       162 $lookup{$rec} = 1 unless ($reserved_partial{$rec}); # see package lexical above
92             }
93 4         46 return %lookup;
94             }
95              
96             sub _process_base {
97 30     30   38 my ($baseref, $rec) = @_;
98 30         30 my @record = @{${$baseref}{$rec}};
  30         29  
  30         97  
99 30         38 my @values;
100 30         62 for (my $q=0; $q < scalar(@record); $q++) {
101 264         524 $values[$q] = $record[$q];
102             }
103 30         167 return @values;
104             }
105              
106             sub _process_secneeded {
107 20     20   30 my ($secneededref, $secref, $rec, $valuesref) = @_;
108 20         24 foreach my $r (sort {$a <=> $b} keys %{$secneededref}) {
  40         82  
  20         65  
109 50         46 my $s = ${$secref}{$rec}->[$r];
  50         84  
110 50         54 push(@{$valuesref}, $s);
  50         101  
111             }
112 20         29 return @{$valuesref};
  20         137  
113             }
114              
115             1;
116              
117             ############################## DOCUMENTATION ##############################
118              
119             =head1 NAME
120              
121             Data::Presenter::Combo::Union
122              
123             =head1 VERSION
124              
125             This document refers to version 1.03 of Data::Presenter::Combo::Union, released February 10, 2008.
126              
127             =head1 DESCRIPTION
128              
129             This package is a subclass of, and inherits from, Data::Presenter::Combo. Please see the Data::Presenter documentation to learn how to use Data::Presenter::Combo::Union.
130              
131             =head1 AUTHOR
132              
133             James E. Keenan (jkeenan@cpan.org).
134              
135             Creation date: October 28, 2001. Last modification date: February 10, 2008.
136             Copyright (c) 2001-5 James E. Keenan. United States. All rights reserved.
137              
138             All data presented in this documentation or in the sample files in the
139             archive accompanying this documentation are dummy copy. The data was
140             entirely fabricated by the author for heuristic purposes. Any resemblance
141             to any person, living or dead, is coincidental.
142              
143             This is free software which you may distribute under the same terms as
144             Perl itself.
145              
146             =cut
147