File Coverage

lib/UR/Value.pm
Criterion Covered Total %
statement 75 75 100.0
branch 22 22 100.0
condition 5 6 83.3
subroutine 11 11 100.0
pod 0 1 0.0
total 113 115 98.2


line stmt bran cond sub pod time code
1             package UR::Value;
2              
3 209     209   7090 use strict;
  209         288  
  209         5508  
4 209     209   733 use warnings;
  209         256  
  209         5957  
5              
6             require UR;
7              
8 209     209   767 use List::MoreUtils;
  209         251  
  209         2498  
9              
10             our $VERSION = "0.46"; # UR $VERSION;
11              
12             our @CARP_NOT = qw( UR::Context );
13              
14             UR::Object::Type->define(
15             class_name => 'UR::Value',
16             is => 'UR::Object',
17             has => ['id'],
18             data_source => 'UR::DataSource::Default',
19             );
20              
21             sub __display_name__ {
22 72     72   176 return shift->id;
23             }
24              
25             sub __load__ {
26 107     107   154 my $class = shift;
27 107         114 my $rule = shift;
28 107         129 my $expected_headers = shift;
29              
30 107         283 my $class_meta = $class->__meta__;
31 107 100       342 unless ($class_meta->{_value_loader}) {
32 34         108 my @id_property_names = $class_meta->all_id_property_names;
33 34         62 my %id_property_names = map { $_ => 1 } @id_property_names;
  43         127  
34              
35             my $loader = sub {
36 107     107   158 my $bx = shift;
37 107         278 my $id = $bx->value_for_id;
38 107 100       249 unless (defined $id) {
39 2         6 Carp::croak "Can't load an infinite set of "
40             . $bx->subject_class_name
41             . ". Some id properties were not specified in the rule $bx";
42             }
43 105         132 my @rows;
44 105 100 100     325 if (ref($id) and ref($id) eq 'ARRAY') {
45             # Multiple IDs passed in - return rows for multiple objects
46 7         22 my @non_id = grep { ! $id_property_names{$_} } $bx->template->_property_names;
  19         35  
47 7 100       23 if (@non_id) {
48 1         3 Carp::croak("Cannot load class "
49             . $bx->subject_class_name
50             . " via UR::DataSource::Default when 'id' is a listref and non-id"
51             . " properties appear in the rule: "
52             . join(', ', @non_id));
53             }
54              
55             # Get the 1st value from each list, then the second, then the third, etc
56             my $iter = List::MoreUtils::each_arrayref
57             map {
58 6         12 my $v = $bx->value_for($_);
  22         43  
59 22 100       74 (ref($v) eq 'ARRAY')
60             ? $v
61             : [ $v ]
62             }
63             @$expected_headers;
64 6         39 while(my @row = $iter->()) {
65 19         78 push @rows, \@row;
66             }
67              
68             } else {
69             # single ID - return a single row
70 98         178 my @row = map { $bx->value_for($_) } @$expected_headers;
  258         496  
71 98         201 @rows = ( \@row );
72             }
73 104         268 return ($expected_headers, \@rows);
74 34         214 };
75              
76 34         127 $class_meta->{_value_loader} = $loader;
77             }
78              
79 107         267 return $class_meta->{_value_loader}->($rule);
80             }
81              
82             sub underlying_data_types {
83 31     31 0 69 return ();
84             }
85              
86             package UR::Value::Type;
87              
88             sub get_composite_id_decomposer {
89 17     17   23 my $class_meta = shift;
90              
91 17 100       47 unless ($class_meta->{get_composite_id_decomposer}) {
92 5         19 my @id_property_names = $class_meta->id_property_names;
93 5         19 my $instance_class = $class_meta->class_name;
94 5 100       21 if (my $decomposer = $instance_class->can('__deserialize_id__')) {
95             $class_meta->{get_composite_id_decomposer} = sub {
96             my @ids = (ref($_[0]) and ref($_[0]) eq 'ARRAY')
97 5 100 66 5   30 ? @{$_[0]}
  2         6  
98             : ( $_[0] );
99 5         7 my @retval;
100 5 100       13 if (@ids == 1) {
101 3         13 my $h = $instance_class->$decomposer($ids[0]);
102 3         29 @retval = @$h{@id_property_names};
103              
104             } else {
105             # Get the 1st value from each list, then the second, then the third, etc
106             my @decomposed = map {
107 2         4 my $h = $instance_class->$decomposer($_);
  5         12  
108 5         29 [ @$h{@id_property_names} ]
109             }
110             @ids;
111 2         12 my $iter = List::MoreUtils::each_arrayref @decomposed;
112              
113 2         11 while( my @row = $iter->() ) {
114 4         17 push @retval, \@row;
115             }
116             }
117 5         16 return @retval;
118 2         27 };
119              
120             } else {
121 3         137 $decomposer = $class_meta->SUPER::get_composite_id_decomposer();
122 3         9 $class_meta->{get_composite_id_decomposer} = $decomposer;
123             }
124             }
125 17         43 return $class_meta->{get_composite_id_decomposer};
126             }
127              
128             sub get_composite_id_resolver {
129 4091     4091   5343 my $class_meta = shift;
130 4091 100       11930 unless ($class_meta->{get_composite_id_resolver}) {
131 177         644 my @id_property_names = $class_meta->id_property_names;
132 177         667 my $instance_class = $class_meta->class_name;
133 177 100       817 if (my $resolver = $instance_class->can('__serialize_id__')) {
134             $class_meta->{get_composite_id_resolver} = sub {
135 13     13   20 my %h = map { $_ => shift } @id_property_names;
  26         60  
136 13         55 return $instance_class->__serialize_id__(\%h);
137 2         28 };
138              
139             } else {
140 175         11435 $resolver = $class_meta->SUPER::get_composite_id_resolver();
141 175         510 $class_meta->{get_composite_id_resolver} = $resolver;
142             }
143             }
144 4091         7507 return $class_meta->{get_composite_id_resolver};
145             }
146              
147              
148              
149             1;