From 7307c8c748e3245d65a25c016e7d92c6c7ae2aa4 Mon Sep 17 00:00:00 2001 From: Max Kanat-Alexander Date: Tue, 5 Oct 2010 01:39:01 -0700 Subject: Bug 26074 - Ability to limit search by number of Comments r=mkanat, a=mkanat (module owner) --- Bugzilla/Comment.pm | 5 ++++- Bugzilla/Field.pm | 2 ++ Bugzilla/Search.pm | 44 +++++++++++++++++++++++++++++++++++++------- 3 files changed, 43 insertions(+), 8 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/Comment.pm b/Bugzilla/Comment.pm index 074f28dd6..b4f94e213 100644 --- a/Bugzilla/Comment.pm +++ b/Bugzilla/Comment.pm @@ -56,7 +56,10 @@ use constant UPDATE_COLUMNS => qw( use constant DB_TABLE => 'longdescs'; use constant ID_FIELD => 'comment_id'; -use constant LIST_ORDER => 'bug_when'; +# In some rare cases, two comments can have identical timestamps. If +# this happens, we want to be sure that the comment added later shows up +# later in the sequence. +use constant LIST_ORDER => 'bug_when, comment_id'; use constant VALIDATORS => { extra_data => \&_check_extra_data, diff --git a/Bugzilla/Field.pm b/Bugzilla/Field.pm index 41b90a644..1229d31cb 100644 --- a/Bugzilla/Field.pm +++ b/Bugzilla/Field.pm @@ -218,6 +218,8 @@ use constant DEFAULT_FIELDS => ( buglist => 1}, {name => 'longdesc', desc => 'Comment'}, {name => 'longdescs.isprivate', desc => 'Comment is private'}, + {name => 'longdescs.count', desc => 'Number of Comments', + buglist => 1}, {name => 'alias', desc => 'Alias', buglist => 1}, {name => 'everconfirmed', desc => 'Ever Confirmed'}, {name => 'reporter_accessible', desc => 'Reporter Accessible'}, diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm index da6f57bf3..cc1354dcf 100644 --- a/Bugzilla/Search.pm +++ b/Bugzilla/Search.pm @@ -272,6 +272,14 @@ use constant OPERATOR_FIELD_OVERRIDE => { changedafter => \&_long_desc_changedbefore_after, _default => \&_long_desc, }, + 'longdescs.count' => { + changedby => \&_long_desc_changedby, + changedbefore => \&_long_desc_changedbefore_after, + changedafter => \&_long_desc_changedbefore_after, + changedfrom => \&_invalid_combination, + changedto => \&_invalid_combination, + _default => \&_long_descs_count, + }, 'longdescs.isprivate' => { _default => \&_longdescs_isprivate, }, @@ -466,6 +474,10 @@ use constant COLUMN_JOINS => { to => 'id', }, }, + 'longdescs.count' => { + table => 'longdescs', + join => 'INNER', + }, }; # This constant defines the columns that can be selected in a query @@ -524,6 +536,8 @@ sub COLUMNS { . $dbh->sql_string_concat('map_flagtypes.name', 'map_flags.status')), 'keywords' => $dbh->sql_group_concat('DISTINCT map_keyworddefs.name'), + + 'longdescs.count' => 'COUNT(DISTINCT map_longdescs_count.comment_id)', ); # Backward-compatibility for old field names. Goes new_name => old_name. @@ -620,6 +634,7 @@ use constant GROUP_BY_SKIP => EMPTY_COLUMN, qw( bug_id flagtypes.name keywords + longdescs.count percentage_complete ); @@ -2171,7 +2186,7 @@ sub _content_matches { COLUMNS->{'relevance'}->{name} = $select_term; } -sub _long_desc { +sub _join_longdescs { my ($self, $args) = @_; my ($chart_id, $joins) = @$args{qw(chart_id joins)}; @@ -2182,22 +2197,37 @@ sub _long_desc { as => $table, extra => $extra, }; + # We only want to do an INNER JOIN if we're not checking isprivate. + # Otherwise we'd exclude all bugs with only private comments from + # the search entirely. + $join->{join} = 'INNER' if $self->_user->is_insider; push(@$joins, $join); + return $table; +} + +sub _long_desc { + my ($self, $args) = @_; + my $table = $self->_join_longdescs($args); $args->{full_field} = "$table.thetext"; } -sub _longdescs_isprivate { +sub _long_descs_count { my ($self, $args) = @_; my ($chart_id, $joins) = @$args{qw(chart_id joins)}; - - my $table = "longdescs_$chart_id"; - my $extra = $self->_user->is_insider ? [] : ["$table.isprivate = 0"]; + my $table = "longdescs_count_$chart_id"; + my $extra = $self->_user->is_insider ? "" : "WHERE isprivate = 0"; my $join = { - table => 'longdescs', + table => "(SELECT bug_id, COUNT(*) AS num" + . " FROM longdescs $extra GROUP BY bug_id)", as => $table, - extra => $extra, }; push(@$joins, $join); + $args->{full_field} = "${table}.num"; +} + +sub _longdescs_isprivate { + my ($self, $args) = @_; + my $table = $self->_join_longdescs($args); $args->{full_field} = "$table.isprivate"; } -- cgit v1.2.3-24-g4f1b