File Coverage

blib/lib/Data/Reconciliation/Rule.pm
Criterion Covered Total %
statement 104 106 98.1
branch 29 40 72.5
condition 15 39 38.4
subroutine 13 15 86.6
pod 5 7 71.4
total 166 207 80.1


line stmt bran cond sub pod time code
1             ##======================================================================
2             ## Authors:
3             ## Martial.Chateauvieux@sfs.siemens.de
4             ## O.Capdevielle@cadextan.fr
5             ##======================================================================
6             ## Copyright (c) 2001, Siemens Financial Services. All rights reserved.
7             ## This library is free software; you can redistribute it and/or modify
8             ## it under the same terms as Perl itself.
9             ##======================================================================
10             ## $Log:$
11             ##======================================================================
12              
13             package Data::Reconciliation::Rule;
14              
15             require 5.005_62;
16 2     2   7330 use strict;
  2         4  
  2         72  
17 2     2   12 use warnings;
  2         3  
  2         55  
18              
19 2     2   10 use Carp;
  2         4  
  2         4141  
20              
21             our $VERSION = '0.01';
22              
23             sub new {
24 3     3 1 20067 my $class = shift;
25 3         8 my $src1 = shift;
26 3         6 my $src2 = shift;
27              
28             croak "Usage: new $class (, )"
29 3         39 if ! eval { $src1->isa('Data::Table') } ||
30 3 50 33     6 ! eval { $src2->isa('Data::Table') };
  3         16  
31              
32 3         20 return bless {
33             'srcs' => [$src1, $src2]
34             }, $class;
35             }
36              
37             sub identification {
38 2     2 1 449 my $this = shift;
39              
40 2 50       11 if (@_ > 0) {
41 2         5 my $field_names_1 = shift;
42 2         4 my $canon_sub_1 = shift;
43 2         6 my $field_names_2 = shift;
44 2         3 my $canon_sub_2 = shift;
45              
46 2         7 foreach (@$field_names_1) {
47 3 50       34 croak "identification: Inavlid column name [$_]"
48             if $this->{'srcs'}->[0]->colIndex($_) == -1;
49             }
50 2         25 foreach (@$field_names_2) {
51 2 50       9 croak "identification: Inavlid column name [$_]"
52             if $this->{'srcs'}->[1]->colIndex($_) == -1;
53             }
54            
55 2         21 my @field_idx_1 = map {$this->{'srcs'}->[0]->colIndex($_)} @$field_names_1;
  3         18  
56 2         17 my @field_idx_2 = map {$this->{'srcs'}->[1]->colIndex($_)} @$field_names_2;
  2         10  
57            
58 6     6   51 $canon_sub_1 = sub { join '|', @_ }
59 2 100       644 if ! defined $canon_sub_1;
60 6     6   35 $canon_sub_2 = sub { join '|', @_ }
61 2 100       11 if ! defined $canon_sub_2;
62            
63 2 50 33     41 croak 'Usage: $rule->identification(\@fields_1, \&canon_sub_1, ' .
      33        
      33        
64             '\@fields_2, \&canon_sub_2);'
65             if ! (('ARRAY' eq ref $field_names_1) &&
66             ('CODE' eq ref $canon_sub_1) &&
67             ('ARRAY' eq ref $field_names_2) &&
68             ('CODE' eq ref $canon_sub_2));
69            
70 2         9 $this->{'field_names'}->[0] = [ @$field_names_1];
71 2         9 $this->{'fields'}->[0] = [ @field_idx_1];
72 2         5 $this->{'canon_sub'}->[0] = $canon_sub_1;
73 2         7 $this->{'field_names'}->[1] = [ @$field_names_2];
74 2         5 $this->{'fields'}->[1] = [ @field_idx_2];
75 2         6 $this->{'canon_sub'}->[1] = $canon_sub_2;
76             }
77              
78 2         8 return ($this->{'fields'}->[0],
79             $this->{'canon_sub'}->[0],
80             $this->{'fields'}->[1],
81             $this->{'canon_sub'}->[1]);
82             }
83              
84             sub isNumber ($) {
85 8 50   8 0 19 return undef if ! defined $_[0];
86 8         62 shift =~ /^\s*([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?\s*$/;
87             }
88              
89             sub trim ($) {
90 14 50   14 0 39 return undef if ! defined $_[0];
91 14         19 my $field = shift;
92 14         59 $field =~ s/\s+$//o;
93 14         22 $field =~ s/^\s+//o;
94 14         36 return $field;
95             }
96              
97             sub add_comparison {
98 4     4 1 519 my $this = shift;
99 4         8 my $field_names_1 = shift;
100 4         4 my $canon_sub_1 = shift;
101 4         7 my $field_names_2 = shift;
102 4         5 my $canon_sub_2 = shift;
103 4         7 my $compare_sub = shift;
104 4         6 my $compare_sub_name = shift;
105 4         6 my $constants = shift;
106            
107 4 50 33     125 croak('usage: $r->add_comparison(',
      66        
      33        
      66        
      33        
      33        
      33        
      33        
      33        
108             '\@field_names_1, \&canon_1, ',
109             '\@field_names_2, \&canon_2, ',
110             '\&compare, $compare_name, \@constants); ')
111             if ! (('ARRAY' eq ref $field_names_1) &&
112             ('ARRAY' eq ref $field_names_2) &&
113             ((! defined $canon_sub_1) || ('CODE' eq ref $canon_sub_1)) &&
114             ((! defined $canon_sub_2) || ('CODE' eq ref $canon_sub_2)) &&
115             ((! defined $compare_sub) || ('CODE' eq ref $compare_sub)) &&
116             ((! defined $constants) || ('ARRAY' eq ref $constants)));
117              
118 4         9 foreach (@$field_names_1) {
119 5 50       27 croak "add_comparison: Inavlid column name [$_]"
120             if $this->{'srcs'}->[0]->colIndex($_) == -1;
121             }
122 4         37 foreach (@$field_names_2) {
123 4 50       15 croak "add_comparison: Inavlid column name [$_]"
124             if $this->{'srcs'}->[1]->colIndex($_) == -1;
125             }
126              
127 4         32 my @field_idx_1 = map {$this->{'srcs'}->[0]->colIndex($_)} @$field_names_1;
  5         22  
128 4         28 my @field_idx_2 = map {$this->{'srcs'}->[1]->colIndex($_)} @$field_names_2;
  4         14  
129              
130 4 50       32 if (! defined $compare_sub) {
131              
132 4 100   0   22 my $sub_1 = defined $canon_sub_1 ? $canon_sub_1 : sub { @_ };
  0         0  
133 4 100   0   15 my $sub_2 = defined $canon_sub_2 ? $canon_sub_2 : sub { @_ };
  0         0  
134              
135             $compare_sub = sub (\@\@\@\@$) {
136 8     8   20 my $field_names_1 = shift;
137 8         10 my $field_values_1 = shift;
138 8         7 my $field_names_2 = shift;
139 8         9 my $field_values_2 = shift;
140 8         10 my $constants = shift;
141 8         10 my $func_name = shift;
142            
143 8         35 my $value_1 = join '|', @$field_values_1;
144 8         16 my $value_2 = join '|', @$field_values_2;
145              
146 8 100       34 if (isNumber($value_1) ?
    100          
147             $value_1 <=> $value_2 :
148             trim($value_1) cmp trim($value_2)) {
149 2         21 return sprintf("SRC1.%s=[%s] <> SRC2.%s=[%s]",
150             join('.', @$field_names_1),
151             $value_1,
152             join('.', @$field_names_2),
153             $value_2);
154             } else {
155 6         14 return undef ;
156             }
157 4         33 };
158             }
159              
160 4         8 push @{$this->{'comparison'}}, [$field_names_1, \@field_idx_1, $canon_sub_1,
  4         23  
161             $field_names_2, \@field_idx_2, $canon_sub_2,
162             $compare_sub, $compare_sub_name, $constants];
163             }
164              
165             sub signature {
166 15     15 1 633 my $this = shift;
167 15         16 my $source_nb = shift;
168 15         19 my $record = shift;
169              
170 15         23 my $fields = $this->{'fields'}->[$source_nb];
171 15         19 my $canon = $this->{'canon_sub'}->[$source_nb];
172              
173 15         29 return &$canon(@{$record}[@$fields]);
  15         42  
174             }
175              
176             sub compare {
177 7     7 1 235 my $this = shift;
178 7         10 my $record_1 = shift; #array ref
179 7         8 my $record_2 = shift; #array ref
180              
181 7         9 my @messages;
182              
183 7         8 foreach my $comp (@{$this->{'comparison'}}) {
  7         15  
184 8         17 my($fnames1, $fidx1, $sub_1,
185             $fnames2, $fidx2, $sub_2,
186             $comp_sub, $comp_sub_name, $consts) = @$comp;
187 1         6 my $msg = &$comp_sub($fnames1,
188             [ defined $sub_1 ?
189 7         22 &$sub_1(@{$record_1}[@$fidx1]) :
190 1         11 @{$record_1}[@$fidx1] ],
191             $fnames2,
192             [ defined $sub_2 ?
193 7         20 &$sub_2(@{$record_2}[@$fidx2]) :
194 8 100       20 @{$record_2}[@$fidx2] ],
    100          
195             $consts,
196             $comp_sub_name);
197 8 100       74 push @messages, $msg if defined $msg;
198             }
199              
200 7         29 return @messages;
201             }
202              
203             1;
204             __END__