-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsearch_include_dependencies_5.0.patch
More file actions
130 lines (127 loc) · 5.09 KB
/
search_include_dependencies_5.0.patch
File metadata and controls
130 lines (127 loc) · 5.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm
index 646f949..c172b88 100644
--- a/Bugzilla/Search.pm
+++ b/Bugzilla/Search.pm
@@ -33,7 +33,7 @@ use Data::Dumper;
use Date::Format;
use Date::Parse;
use Scalar::Util qw(blessed);
-use List::MoreUtils qw(all firstidx part uniq);
+use List::MoreUtils qw(all firstidx part uniq any);
use POSIX qw(INT_MAX floor);
use Storable qw(dclone);
use Time::HiRes qw(gettimeofday tv_interval);
@@ -163,6 +163,10 @@ use constant OPERATORS => {
changedby => \&_changedby,
isempty => \&_isempty,
isnotempty => \&_isnotempty,
+ anddependson => \&_withdependencies,
+ andblocked => \&_withdependencies,
+ notdependson => \&_excludedependencies,
+ notblocked => \&_excludedependencies,
};
# Some operators are really just standard SQL operators, and are
@@ -3374,6 +3378,61 @@ sub _empty_value {
return "''";
}
+sub _get_dependencies {
+ my ($from, $to, @ids) = @_;
+ my $dbh = Bugzilla->dbh;
+ return () unless @ids;
+
+ my @depends = @{$dbh->selectcol_arrayref(
+ "SELECT ".$to.
+ " FROM dependencies ".
+ "WHERE ".$from." IN(".join(",",map ("?", @ids)).")",
+ , undef, @ids)};
+ return @depends;
+}
+
+sub _withdependencies {
+ my ($self, $args) = @_;
+ my ($field, $full_field, $operator) =
+ @$args{qw(field full_field operator)};
+
+ ThrowUserError("search_field_operator_invalid",
+ { field => $field, operator => $operator })
+ unless ($field eq "bug_id");
+
+ my $dbh = Bugzilla->dbh;
+ my @ids = $self->_all_values($args);
+ detaint_natural($_) for (@ids);
+
+ my ($from, $to) = $operator eq "anddependson" ?
+ qw(blocked dependson):
+ qw(dependson blocked);
+
+ my @depends = _get_dependencies($from, $to, @ids);
+ while (@depends) {
+ my @new_ids;
+ for my $id (@depends) {
+ push @new_ids, $id unless grep($_ == $id, @ids)
+ }
+ push @ids, @new_ids;
+ @depends = _get_dependencies($from, $to, @new_ids);
+ }
+ if (@ids) {
+ $args->{term} = $dbh->sql_in($full_field, \@ids);
+ }
+ else {
+ $args->{term} = '';
+ }
+}
+
+sub _excludedependencies {
+ my ($self, $args) = @_;
+ $args->{operator} = $args->{operator} eq "notdependson" ?
+ "anddependson" : "andblocked";
+ $self->_withdependencies($args);
+ $args->{term} = "NOT(".$args->{term}.")";
+}
+
######################
# Public Subroutines #
######################
diff --git a/template/en/default/global/field-descs.none.tmpl b/template/en/default/global/field-descs.none.tmpl
index f4e17c3..21f9a2e 100644
--- a/template/en/default/global/field-descs.none.tmpl
+++ b/template/en/default/global/field-descs.none.tmpl
@@ -37,6 +37,10 @@
"notmatches" => "does not match",
"isempty" => "is empty",
"isnotempty" => "is not empty",
+ "anddependson" => "and depends on",
+ "andblocked" => "and blocked",
+ "notdependson" => "nor any dependencies",
+ "notblocked" => "nor any blocked",
} %]
[% field_types = { ${constants.FIELD_TYPE_UNKNOWN} => "Unknown Type",
diff --git a/template/en/default/list/list.html.tmpl b/template/en/default/list/list.html.tmpl
index 368cd9c..d7c0b55 100644
--- a/template/en/default/list/list.html.tmpl
+++ b/template/en/default/list/list.html.tmpl
@@ -105,7 +105,8 @@
'notequals', 'regexp', 'notregexp', 'lessthan', 'lessthaneq',
'greaterthan', 'greaterthaneq', 'changedbefore', 'changedafter',
'changedfrom', 'changedto', 'changedby', 'notsubstring', 'nowords',
- 'nowordssubstr', 'notmatches', 'isempty', 'isnotempty'
+ 'nowordssubstr', 'notmatches', 'isempty', 'isnotempty',
+ 'anddependson', 'andblocked', 'notdependson', 'notblocked',
] %]
<a id="search_description_controller" class="bz_default_hidden"
href="javascript:TUI_toggle_class('search_description')">Hide Search Description</a>
diff --git a/template/en/default/search/form.html.tmpl b/template/en/default/search/form.html.tmpl
index ac8aeaf..7dd5f38 100644
--- a/template/en/default/search/form.html.tmpl
+++ b/template/en/default/search/form.html.tmpl
@@ -172,6 +172,10 @@ TUI_hide_default('information_query');
<select name="bug_id_type" id="bug_id_type">
<option value="anyexact"[% " selected" IF default.bug_id_type.0 == "anyexact" %]>only included in</option>
<option value="nowords"[% " selected" IF default.bug_id_type.0 == "nowords" %]>excluded from</option>
+ <option value="anddependson"[% " selected" IF default.bug_id_type.0 == "anddependson" %]>included, with all [% terms.bugs %] they depend on, in</option>
+ <option value="andblocked"[% " selected" IF default.bug_id_type.0 == "andblocked" %]>included, with all [% terms.bugs %] they block, in</option>
+ <option value="notdependson"[% " selected" IF default.bug_id_type.0 == "notdependson" %]>excluded, with all [% terms.bugs %] they depend on, in</option>
+ <option value="notblocked"[% " selected" IF default.bug_id_type.0 == "notblocked" %]>excluded, with all [% terms.bugs %] they block, in</option>
</select> the results
</span>
</div>