File Coverage

blib/lib/DBR/Config/Trans/Enum.pm
Criterion Covered Total %
statement 69 96 71.8
branch 13 26 50.0
condition 9 18 50.0
subroutine 13 24 54.1
pod 0 5 0.0
total 104 169 61.5


line stmt bran cond sub pod time code
1             package DBR::Config::Trans::Enum;
2              
3 18     18   108 use strict;
  18         38  
  18         880  
4 18     18   100 use base 'DBR::Config::Trans';
  18         35  
  18         1861  
5              
6 18     18   110 use Clone qw(clone);
  18         36  
  18         4932  
7             use constant {
8             # Cache Constants
9 18         58656 x_list => 0,
10             x_hmap => 1,
11             x_idmap => 2,
12              
13             # Value Constants
14             v_id => 0,
15             v_handle => 1,
16             v_name => 2,
17 18     18   333 };
  18         171  
18              
19             my %FIELDMAP;
20              
21             sub moduleload{
22 24     24 0 66 my( $package ) = shift;
23 24         98 my %params = @_;
24              
25 24         103 my $self = { session => $params{session} };
26 24         107 bless( $self, $package ); # Dummy object
27              
28 24   50     106 my $instance = $params{instance} || return $self->_error('instance is required');
29              
30 24   50     106 my $field_ids = $params{field_id} || return $self->_error('field_id is required');
31 24 50       101 $field_ids = [$field_ids] unless ref($field_ids) eq 'ARRAY';
32              
33 24   50     186 my $dbrh = $instance->connect || return $self->_error("Failed to connect to ${\$instance->name}");
34              
35 24 50       285 return $self->_error('Failed to select from enum_map') unless
36             my $maps = $dbrh->select(
37             -table => 'enum_map',
38             -fields => 'field_id enum_id sortval',
39             -where => { field_id => ['d in',@$field_ids] },
40             );
41              
42 24         345 my @enumids = $self->_uniq( map { $_->{enum_id} } @$maps);
  107         304  
43              
44 24         79 my $values = [];
45 24 100       114 if(@enumids){
46 14 50       366 return $self->_error('Failed to select from enum') unless
47             $values = $dbrh->select(
48             -table => 'enum',
49             -fields => 'enum_id handle name override_id',
50             -where => { enum_id => ['d in',@enumids ] },
51             );
52             }
53              
54 24         114 my %VALUES_BY_ID;
55 24         96 foreach my $value (@$values){
56 107         1270 my $enum_id = $value->{enum_id};
57 107 100       239 my $id = defined($value->{override_id}) ? $value->{override_id} : $enum_id;
58              
59 107         431 $VALUES_BY_ID{ $enum_id } = [$id,$value->{handle},$value->{name}]; #
60             }
61              
62 24   50     232 foreach my $map (sort {( $a->{sortval}||0 ) <=> ( $b->{sortval}||0 ) } @$maps){
  205   50     2103  
63 107         175 my $enum_id = $map->{enum_id};
64 107         1113 my $value = $VALUES_BY_ID{ $enum_id };
65              
66 107   100     1782 my $ref = $FIELDMAP{ $map->{field_id} } ||=[];
67 107         129 push @{$ref->[ x_list ]}, $value;
  107         287  
68 107         316 $ref->[ x_hmap ]->{ $value->[ v_handle ] } = $value; # Forward
69 107         418 $ref->[ x_idmap ]->{ $value->[ v_id ] } = $value; # Backward
70              
71             }
72              
73 24         344 return 1;
74             }
75              
76              
77 0     0 0 0 sub new { die "Should not get here" }
78              
79             sub options{
80 0     0 0 0 my $self = shift;
81              
82 0         0 my $opts = $FIELDMAP{ $self->{field_id} }->[ x_list ];
83 0         0 return [ map { bless([$_,$self->{field_id}], 'DBR::_ENUM') } @$opts ];
  0         0  
84             }
85              
86             sub forward{
87 1     1 0 2 my $self = shift;
88 1         3 my $id = shift;
89              
90 1 50       5 if (defined($id)){
91 1         14 return bless( [ $FIELDMAP{ $self->{field_id} }->[ x_idmap ]->{ $id }, $self->{field_id} ] , 'DBR::_ENUM');
92             }else{
93             # Looks like a null value. return a dummy object
94 0         0 return bless( [ ['','',''] , $self->{field_id} ] , 'DBR::_ENUM');
95             }
96             }
97              
98              
99             sub backward{
100 20     20 0 38 my $self = shift;
101 20         37 my $value = shift;
102              
103 20 100 66     216 return undef unless defined($value) && length($value);
104              
105 19 50       67 if( ref($value) eq 'DBR::_ENUM' ){ # smells like an enum object
106 0         0 $value = $value->handle; # swap it out for the handle, so we can make sure they didn't mix up enum objects
107 0         0 return $FIELDMAP{ $self->{field_id} }->[ x_hmap ]->{ $value }->[ v_id ]; # id
108             }
109              
110 19         35 my @out;
111 19         129 foreach ( $self->_split($value) ){
112             #otherwise hit the lookup
113 21         106 my $id = $FIELDMAP{ $self->{field_id} }->[ x_hmap ]->{ $_ }->[ v_id ];
114 21 100       74 return () unless defined($id);
115              
116 20         72 push @out, $id;
117             }
118              
119 18         140 return @out;
120              
121             }
122              
123             ###############################################################################################################
124             ###############################################################################################################
125             ###############################################################################################################
126             ###############################################################################################################
127              
128             package DBR::_ENUM;
129              
130             use constant {
131             # Cache Constants
132 18         2186 x_list => 0,
133             x_hmap => 1,
134             x_idmap => 2,
135              
136             # Value Constants
137             v_id => 0,
138             v_handle => 1,
139             v_name => 2,
140 18     18   149 };
  18         52  
141 18     18   162 use strict;
  18         40  
  18         547  
142 18     18   113 use Carp;
  18         54  
  18         3922  
143             use overload
144             # Values
145 1     1   69 '""' => sub { $_[0]->name },
146              
147             # Operators
148 0     0   0 'eq' => sub { $_[0]->handle eq _strhandle($_[1]) },
149 0     0   0 'ne' => sub { $_[0]->handle ne _strhandle($_[1]) },
150 0     0   0 'nomethod' => sub {croak "Enum object: Invalid operation '$_[3]' The ways in which you can use an enum are restricted"}
151 18     18   124 ;
  18         42  
  18         475  
152              
153             *TO_JSON = \&chunk;
154              
155 0     0   0 sub id { $_[0][0]->[ v_id ] }
156 0     0   0 sub handle { $_[0][0]->[ v_handle ] }
157 1     1   10 sub name { $_[0][0]->[ v_name ] }
158 0     0     sub chunk {return { handle => $_[0]->handle, name => $_[0]->name} }
159 0     0     sub field_id { $_[0][1] }
160              
161             sub in{
162 0     0     my $self = shift;
163              
164 0 0         my $hmap = $FIELDMAP{ $self->field_id }->[ x_hmap ] or die 'Unable to locate field in cache';
165              
166 0           my $id = $self->id;
167 0 0         my @ids = map {
168 0           $hmap->{$_}->[ v_id ] or croak "Enum->in: Invalid value $_"
169             }
170             map {
171 0           split(/\s+/,$_)
172             } @_;
173              
174 0 0         map { return 1 if $id eq $_ } @ids;
  0            
175              
176 0           return 0;
177             }
178              
179             #######################################
180             ######### Util ####################
181             #######################################
182              
183             sub _strhandle{
184 0   0 0     my $val = $_[1] || $_[0]; # can be OO or functional
185 0 0         return $val->handle if ref($val) eq __PACKAGE__;
186 0           return $val;
187             }
188              
189              
190             1;