From da12cec61f8c7e667b00fc5fc39c827d3593f021 Mon Sep 17 00:00:00 2001 From: Byron Jones Date: Thu, 22 Nov 2012 16:23:53 +0800 Subject: Bug 780820: Allows for multiple custom search criteria to match one field r=dkl,a=LpSolit --- Bugzilla/Search/Clause.pm | 7 ++- Bugzilla/Search/ClauseGroup.pm | 97 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 Bugzilla/Search/ClauseGroup.pm (limited to 'Bugzilla/Search') diff --git a/Bugzilla/Search/Clause.pm b/Bugzilla/Search/Clause.pm index ff50cb944..77969440e 100644 --- a/Bugzilla/Search/Clause.pm +++ b/Bugzilla/Search/Clause.pm @@ -30,6 +30,11 @@ sub children { return $self->{children}; } +sub update_search_args { + my ($self, $search_args) = @_; + # abstract +} + sub joiner { return $_[0]->{joiner} } sub has_translated_conditions { @@ -71,7 +76,7 @@ sub walk_conditions { my ($self, $callback) = @_; foreach my $child (@{ $self->children }) { if ($child->isa('Bugzilla::Search::Condition')) { - $callback->($child); + $callback->($self, $child); } else { $child->walk_conditions($callback); diff --git a/Bugzilla/Search/ClauseGroup.pm b/Bugzilla/Search/ClauseGroup.pm new file mode 100644 index 000000000..98c9779c9 --- /dev/null +++ b/Bugzilla/Search/ClauseGroup.pm @@ -0,0 +1,97 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Search::ClauseGroup; + +use 5.10.1; +use strict; + +use base qw(Bugzilla::Search::Clause); + +use Bugzilla::Error; +use Bugzilla::Search::Condition qw(condition); +use Bugzilla::Util qw(trick_taint); +use List::MoreUtils qw(uniq); + +use constant UNSUPPORTED_FIELDS => qw( + attach_data.thedata + classification + commenter + component + longdescs.count + product + owner_idle_time +); + +sub new { + my ($class) = @_; + my $self = bless({ joiner => 'AND' }, $class); + # Add a join back to the bugs table which will be used to group conditions + # for this clause + my $condition = Bugzilla::Search::Condition->new({}); + $condition->translated({ + joins => [{ + table => 'bugs', + as => 'bugs_g0', + from => 'bug_id', + to => 'bug_id', + extra => [], + }], + term => '1 = 1', + }); + $self->SUPER::add($condition); + $self->{group_condition} = $condition; + return $self; +} + +sub add { + my ($self, @args) = @_; + my $field = scalar(@args) == 3 ? $args[0] : $args[0]->{field}; + + # We don't support nesting of conditions under this clause + if (scalar(@args) == 1 && !$args[0]->isa('Bugzilla::Search::Condition')) { + ThrowUserError('search_grouped_invalid_nesting'); + } + + # Ensure all conditions use the same field + if (!$self->{_field}) { + $self->{_field} = $field; + } elsif ($field ne $self->{_field}) { + ThrowUserError('search_grouped_field_mismatch'); + } + + # Unsupported fields + if (grep { $_ eq $field } UNSUPPORTED_FIELDS ) { + ThrowUserError('search_grouped_field_invalid', { field => $field }); + } + + $self->SUPER::add(@args); +} + +sub update_search_args { + my ($self, $search_args) = @_; + + # No need to change things if there's only one child condition + return unless scalar(@{ $self->children }) > 1; + + # we want all the terms to use the same join table + if (!exists $self->{_first_chart_id}) { + $self->{_first_chart_id} = $search_args->{chart_id}; + } else { + $search_args->{chart_id} = $self->{_first_chart_id}; + } + + my $suffix = '_g' . $self->{_first_chart_id}; + $self->{group_condition}->{translated}->{joins}->[0]->{as} = "bugs$suffix"; + + $search_args->{full_field} =~ s/^bugs\./bugs$suffix\./; + + $search_args->{table_suffix} = $suffix; + $search_args->{bugs_table} = "bugs$suffix"; +} + +1; -- cgit v1.2.3-24-g4f1b