line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package UR::BoolExpr::Template::Or; |
2
|
|
|
|
|
|
|
|
3
|
266
|
|
|
266
|
|
1078
|
use warnings; |
|
266
|
|
|
|
|
339
|
|
|
266
|
|
|
|
|
8347
|
|
4
|
266
|
|
|
266
|
|
928
|
use strict; |
|
266
|
|
|
|
|
319
|
|
|
266
|
|
|
|
|
222705
|
|
5
|
|
|
|
|
|
|
our $VERSION = "0.46"; # UR $VERSION;; |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
require UR; |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
UR::Object::Type->define( |
10
|
|
|
|
|
|
|
class_name => __PACKAGE__, |
11
|
|
|
|
|
|
|
is => ['UR::BoolExpr::Template::Composite'], |
12
|
|
|
|
|
|
|
); |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
sub _flatten_bx { |
15
|
1
|
|
|
1
|
|
3
|
my ($class, $bx) = @_; |
16
|
1
|
|
|
|
|
5
|
my @old = $bx->underlying_rules; |
17
|
1
|
|
|
|
|
1
|
my @new; |
18
|
1
|
|
|
|
|
3
|
for my $old (@old) { |
19
|
2
|
|
|
|
|
4
|
my $new = $old->flatten; |
20
|
2
|
|
|
|
|
7
|
push @new, [ $new->_params_list ]; |
21
|
|
|
|
|
|
|
} |
22
|
1
|
|
|
|
|
4
|
my $flattened_bx = $class->_compose($bx->subject_class_name,\@new); |
23
|
1
|
|
|
|
|
3
|
return $flattened_bx; |
24
|
|
|
|
|
|
|
} |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
sub _reframe_bx { |
27
|
1
|
|
|
1
|
|
2
|
my ($class, $bx, $in_terms_of) = @_; |
28
|
1
|
|
|
|
|
4
|
my @old = $bx->underlying_rules; |
29
|
1
|
|
|
|
|
3
|
my @new; |
30
|
1
|
|
|
|
|
4
|
for my $old (@old) { |
31
|
2
|
|
|
|
|
9
|
my $new = $old->reframe($in_terms_of); |
32
|
2
|
|
|
|
|
7
|
push @new, [ $new->_params_list ]; |
33
|
|
|
|
|
|
|
} |
34
|
1
|
|
|
|
|
5
|
my @meta = $bx->subject_class_name->__meta__->property_meta_for_name($in_terms_of); |
35
|
1
|
|
|
|
|
5
|
my @joins = $meta[-1]->_resolve_join_chain($in_terms_of); |
36
|
1
|
|
|
|
|
5
|
my $reframed_bx = $class->_compose($joins[-1]{foreign_class},\@new); |
37
|
1
|
|
|
|
|
5
|
return $reframed_bx; |
38
|
|
|
|
|
|
|
} |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
sub _compose { |
41
|
33
|
|
|
33
|
|
45
|
my $self = shift; |
42
|
33
|
|
|
|
|
39
|
my $subject_class = shift; |
43
|
33
|
|
|
|
|
40
|
my $sub_queries = shift; |
44
|
33
|
|
|
|
|
39
|
my $meta_params = shift; |
45
|
|
|
|
|
|
|
|
46
|
33
|
|
|
|
|
42
|
my @underlying_rules; |
47
|
|
|
|
|
|
|
my @expressions; |
48
|
0
|
|
|
|
|
0
|
my @values; |
49
|
33
|
|
|
|
|
75
|
while (@$sub_queries) { |
50
|
78
|
|
|
|
|
65
|
my $underlying_query; |
51
|
78
|
50
|
|
|
|
176
|
if (ref($sub_queries->[0]) eq 'ARRAY') { |
|
|
0
|
|
|
|
|
|
52
|
78
|
|
|
|
|
83
|
$underlying_query = UR::BoolExpr->resolve($subject_class, @{$sub_queries->[0]}, @$meta_params); |
|
78
|
|
|
|
|
270
|
|
53
|
78
|
|
|
|
|
104
|
shift @$sub_queries; |
54
|
|
|
|
|
|
|
} |
55
|
|
|
|
|
|
|
elsif (ref($sub_queries->[0]) eq 'UR::BoolExpr::And') { |
56
|
0
|
|
|
|
|
0
|
$underlying_query = shift @$sub_queries; |
57
|
|
|
|
|
|
|
} |
58
|
|
|
|
|
|
|
else { |
59
|
0
|
|
|
|
|
0
|
$underlying_query = UR::BoolExpr->resolve($subject_class, @$sub_queries[0,1], @$meta_params); |
60
|
0
|
|
|
|
|
0
|
shift @$sub_queries; |
61
|
0
|
|
|
|
|
0
|
shift @$sub_queries; |
62
|
|
|
|
|
|
|
} |
63
|
|
|
|
|
|
|
|
64
|
78
|
50
|
|
|
|
169
|
if ($underlying_query->{'_constant_values'}) { |
65
|
0
|
|
|
|
|
0
|
Carp::confess("cannot use -* expressions in subordinate clauses of a logical "); |
66
|
|
|
|
|
|
|
} |
67
|
|
|
|
|
|
|
|
68
|
78
|
50
|
|
|
|
206
|
unless ($underlying_query->template->isa("UR::BoolExpr::Template::And")) { |
69
|
0
|
|
|
|
|
0
|
Carp::confess("$underlying_query is not an AND template"); |
70
|
|
|
|
|
|
|
} |
71
|
78
|
|
|
|
|
99
|
push @underlying_rules, $underlying_query; |
72
|
|
|
|
|
|
|
|
73
|
78
|
|
|
|
|
140
|
push @expressions, $underlying_query->template->logic_detail; |
74
|
78
|
|
|
|
|
199
|
push @values, $underlying_query->values; |
75
|
|
|
|
|
|
|
} |
76
|
33
|
|
|
|
|
222
|
my $bxt = UR::BoolExpr::Template::Or->get_by_subject_class_name_logic_type_and_logic_detail($subject_class,'Or',join('|',@expressions)); |
77
|
33
|
|
|
|
|
124
|
my $bx = $bxt->get_rule_for_values(@values); |
78
|
|
|
|
|
|
|
# This (and accompanying "caching" in UR::BoolExpr::underlying_rules()) |
79
|
|
|
|
|
|
|
# is a giant hack to allow composite rules to have -order and -group |
80
|
|
|
|
|
|
|
# The real fix is to coax the above combination of |
81
|
|
|
|
|
|
|
# get_by_subject_class_name_logic_type_and_logic_detail() and get_rule_for_values() to |
82
|
|
|
|
|
|
|
# properly encode these constant/template values into the rule and template IDs, |
83
|
|
|
|
|
|
|
# and subsequently reconsitiute them when you call $template->order_by |
84
|
33
|
|
|
|
|
69
|
$bx->{'_underlying_rules'} = \@underlying_rules; |
85
|
33
|
|
|
|
|
116
|
for (my $i = 0; $i < @$meta_params; $i += 2) { |
86
|
3
|
|
|
|
|
7
|
my $method = $meta_params->[$i]; |
87
|
3
|
|
|
|
|
7
|
substr($method, 0, 1, ''); # remove the - |
88
|
3
|
50
|
|
|
|
15
|
if ($method eq 'recurse') { |
|
|
100
|
|
|
|
|
|
89
|
0
|
|
|
|
|
0
|
$bx->template->recursion_desc($meta_params->[$i + 1]); |
90
|
|
|
|
|
|
|
} elsif ($method eq 'order') { |
91
|
2
|
|
|
|
|
7
|
$bx->template->order_by($meta_params->[$i + 1]); |
92
|
|
|
|
|
|
|
} else { |
93
|
1
|
|
|
|
|
3
|
$bx->template->$method($meta_params->[$i + 1]); |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
} |
96
|
|
|
|
|
|
|
|
97
|
33
|
|
|
|
|
99
|
return $bx; |
98
|
|
|
|
|
|
|
} |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
sub _underlying_keys { |
101
|
3
|
|
|
3
|
|
22
|
my $self = shift; |
102
|
3
|
|
|
|
|
13
|
my $logic_detail = $self->logic_detail; |
103
|
3
|
50
|
|
|
|
7
|
return unless $logic_detail; |
104
|
3
|
|
|
|
|
11
|
my @underlying_keys = split('\|',$logic_detail); |
105
|
3
|
|
|
|
|
8
|
return @underlying_keys; |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
# sub get_underlying_rules_for_values |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
sub get_underlying_rule_templates { |
111
|
3
|
|
|
3
|
0
|
5
|
my $self = shift; |
112
|
3
|
|
|
|
|
8
|
my @underlying_keys = $self->_underlying_keys(); |
113
|
3
|
|
|
|
|
11
|
my $subject_class_name = $self->subject_class_name; |
114
|
|
|
|
|
|
|
return map { |
115
|
3
|
|
|
|
|
4
|
UR::BoolExpr::Template::And |
|
6
|
|
|
|
|
26
|
|
116
|
|
|
|
|
|
|
->_get_for_subject_class_name_and_logic_detail( |
117
|
|
|
|
|
|
|
$subject_class_name, |
118
|
|
|
|
|
|
|
$_ |
119
|
|
|
|
|
|
|
); |
120
|
|
|
|
|
|
|
} @underlying_keys; |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
sub specifies_value_for { |
124
|
0
|
|
|
0
|
0
|
0
|
my ($self, $property_name) = @_; |
125
|
0
|
0
|
|
|
|
0
|
Carp::confess() if not defined $property_name; |
126
|
0
|
|
|
|
|
0
|
my @underlying_templates = $self->get_underlying_rule_templates(); |
127
|
0
|
|
|
|
|
0
|
my @all_specified; |
128
|
0
|
|
|
|
|
0
|
for my $template (@underlying_templates) { |
129
|
0
|
|
|
|
|
0
|
my @specified = $template->specifies_value_for($property_name); |
130
|
0
|
0
|
|
|
|
0
|
if (@specified) { |
131
|
0
|
|
|
|
|
0
|
push @all_specified, @specified; |
132
|
|
|
|
|
|
|
} |
133
|
|
|
|
|
|
|
else { |
134
|
0
|
|
|
|
|
0
|
return; |
135
|
|
|
|
|
|
|
} |
136
|
|
|
|
|
|
|
} |
137
|
0
|
|
|
|
|
0
|
return @all_specified; |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
sub evaluate_subject_and_values { |
141
|
0
|
|
|
0
|
0
|
0
|
my $self = shift; |
142
|
0
|
|
|
|
|
0
|
my $subject = shift; |
143
|
0
|
0
|
0
|
|
|
0
|
return unless (ref($subject) && $subject->isa($self->subject_class_name)); |
144
|
0
|
|
|
|
|
0
|
my @underlying = $self->get_underlying_rule_templates; |
145
|
0
|
|
|
|
|
0
|
while (my $underlying = shift (@underlying)) { |
146
|
0
|
|
|
|
|
0
|
my $n = $underlying->_variable_value_count; |
147
|
0
|
|
|
|
|
0
|
my @next_values = splice(@_,0,$n); |
148
|
0
|
0
|
|
|
|
0
|
if ($underlying->evaluate_subject_and_values($subject,@_)) { |
149
|
0
|
|
|
|
|
0
|
return 1; |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
} |
152
|
0
|
|
|
|
|
0
|
return; |
153
|
|
|
|
|
|
|
} |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
sub params_list_for_values { |
156
|
1
|
|
|
1
|
0
|
2
|
my $self = shift; |
157
|
1
|
|
|
|
|
2
|
my @values_sorted = @_; |
158
|
1
|
|
|
|
|
2
|
my @list; |
159
|
1
|
|
|
|
|
4
|
my @t = $self->get_underlying_rule_templates; |
160
|
1
|
|
|
|
|
3
|
for my $t (@t) { |
161
|
2
|
|
|
|
|
6
|
my $c = $t->_variable_value_count; |
162
|
2
|
|
|
|
|
7
|
my @l = $t->params_list_for_values(splice(@values_sorted,0,$c)); |
163
|
2
|
|
|
|
|
5
|
push @list, \@l; |
164
|
|
|
|
|
|
|
} |
165
|
1
|
|
|
|
|
5
|
return -or => \@list; |
166
|
|
|
|
|
|
|
} |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
sub get_normalized_rule_for_values { |
169
|
9
|
|
|
9
|
0
|
15
|
my $self = shift; |
170
|
9
|
|
|
|
|
22
|
return $self->get_rule_for_values(@_); |
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
1; |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
=pod |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
=head1 NAME |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
UR::BoolExpr::Or - a rule which is true if ANY of the underlying conditions are true |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
=head1 SEE ALSO |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
UR::BoolExpr;(3) |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
=cut |