| 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 |