summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Bugzilla/Search.pm321
1 files changed, 164 insertions, 157 deletions
diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm
index 80e8dce43..2f7dfdcad 100644
--- a/Bugzilla/Search.pm
+++ b/Bugzilla/Search.pm
@@ -1629,79 +1629,11 @@ sub _pick_override_function {
# Search Function Helpers #
###########################
-sub SqlifyDate {
- my ($str) = @_;
- $str = "" if !defined $str;
- if ($str eq "") {
- my ($sec, $min, $hour, $mday, $month, $year, $wday) = localtime(time());
- return sprintf("%4d-%02d-%02d 00:00:00", $year+1900, $month+1, $mday);
- }
-
-
- if ($str =~ /^(-|\+)?(\d+)([hHdDwWmMyY])$/) { # relative date
- my ($sign, $amount, $unit, $date) = ($1, $2, lc $3, time);
- my ($sec, $min, $hour, $mday, $month, $year, $wday) = localtime($date);
- if ($sign && $sign eq '+') { $amount = -$amount; }
- if ($unit eq 'w') { # convert weeks to days
- $amount = 7*$amount + $wday;
- $unit = 'd';
- }
- if ($unit eq 'd') {
- $date -= $sec + 60*$min + 3600*$hour + 24*3600*$amount;
- return time2str("%Y-%m-%d %H:%M:%S", $date);
- }
- elsif ($unit eq 'y') {
- return sprintf("%4d-01-01 00:00:00", $year+1900-$amount);
- }
- elsif ($unit eq 'm') {
- $month -= $amount;
- while ($month<0) { $year--; $month += 12; }
- return sprintf("%4d-%02d-01 00:00:00", $year+1900, $month+1);
- }
- elsif ($unit eq 'h') {
- # Special case 0h for 'beginning of this hour'
- if ($amount == 0) {
- $date -= $sec + 60*$min;
- } else {
- $date -= 3600*$amount;
- }
- return time2str("%Y-%m-%d %H:%M:%S", $date);
- }
- return undef; # should not happen due to regexp at top
- }
- my $date = str2time($str);
- if (!defined($date)) {
- ThrowUserError("illegal_date", { date => $str });
- }
- return time2str("%Y-%m-%d %H:%M:%S", $date);
-}
-
sub build_subselect {
my ($outer, $inner, $table, $cond) = @_;
return "$outer IN (SELECT $inner FROM $table WHERE $cond)";
}
-sub pronoun {
- my ($noun, $user) = (@_);
- if ($noun eq "%user%") {
- if ($user->id) {
- return $user->id;
- } else {
- ThrowUserError('login_required_for_pronoun');
- }
- }
- if ($noun eq "%reporter%") {
- return "bugs.reporter";
- }
- if ($noun eq "%assignee%") {
- return "bugs.assigned_to";
- }
- if ($noun eq "%qacontact%") {
- return "bugs.qa_contact";
- }
- return 0;
-}
-
# Used by anyexact to get the list of input values. This allows us to
# support values with commas inside of them in the standard charts, and
# still accept string values for the boolean charts (and split them on
@@ -1773,67 +1705,95 @@ sub _word_terms {
return @terms;
}
-######################
-# Public Subroutines #
-######################
+#####################################
+# "Special Parsing" Functions: Date #
+#####################################
-# Validate that the query type is one we can deal with
-sub IsValidQueryType
-{
- my ($queryType) = @_;
- if (grep { $_ eq $queryType } qw(specific advanced)) {
- return 1;
- }
- return 0;
-}
+sub _timestamp_translate {
+ my ($self, $args) = @_;
+ my $value = $args->{value};
+ my $dbh = Bugzilla->dbh;
-# Splits out "asc|desc" from a sort order item.
-sub split_order_term {
- my $fragment = shift;
- $fragment =~ /^(.+?)(?:\s+(ASC|DESC))?$/i;
- my ($column_name, $direction) = (lc($1), uc($2 || ''));
- return wantarray ? ($column_name, $direction) : $column_name;
+ return if $value !~ /^[\+\-]?\d+[hdwmy]$/i;
+
+ $args->{value} = SqlifyDate($value);
+ $args->{quoted} = $dbh->quote($args->{value});
}
-# Used to translate old SQL fragments from buglist.cgi's "order" argument
-# into our modern field IDs.
-sub translate_old_column {
- my ($column) = @_;
- # All old SQL fragments have a period in them somewhere.
- return $column if $column !~ /\./;
-
- if ($column =~ /\bAS\s+(\w+)$/i) {
- return $1;
+sub SqlifyDate {
+ my ($str) = @_;
+ $str = "" if !defined $str;
+ if ($str eq "") {
+ my ($sec, $min, $hour, $mday, $month, $year, $wday) = localtime(time());
+ return sprintf("%4d-%02d-%02d 00:00:00", $year+1900, $month+1, $mday);
}
- # product, component, classification, assigned_to, qa_contact, reporter
- elsif ($column =~ /map_(\w+?)s?\.(login_)?name/i) {
- return $1;
+
+ if ($str =~ /^(-|\+)?(\d+)([hHdDwWmMyY])$/) { # relative date
+ my ($sign, $amount, $unit, $date) = ($1, $2, lc $3, time);
+ my ($sec, $min, $hour, $mday, $month, $year, $wday) = localtime($date);
+ if ($sign && $sign eq '+') { $amount = -$amount; }
+ if ($unit eq 'w') { # convert weeks to days
+ $amount = 7*$amount + $wday;
+ $unit = 'd';
+ }
+ if ($unit eq 'd') {
+ $date -= $sec + 60*$min + 3600*$hour + 24*3600*$amount;
+ return time2str("%Y-%m-%d %H:%M:%S", $date);
+ }
+ elsif ($unit eq 'y') {
+ return sprintf("%4d-01-01 00:00:00", $year+1900-$amount);
+ }
+ elsif ($unit eq 'm') {
+ $month -= $amount;
+ while ($month<0) { $year--; $month += 12; }
+ return sprintf("%4d-%02d-01 00:00:00", $year+1900, $month+1);
+ }
+ elsif ($unit eq 'h') {
+ # Special case 0h for 'beginning of this hour'
+ if ($amount == 0) {
+ $date -= $sec + 60*$min;
+ } else {
+ $date -= 3600*$amount;
+ }
+ return time2str("%Y-%m-%d %H:%M:%S", $date);
+ }
+ return undef; # should not happen due to regexp at top
}
-
- # If it doesn't match the regexps above, check to see if the old
- # SQL fragment matches the SQL of an existing column
- foreach my $key (%{ COLUMNS() }) {
- next unless exists COLUMNS->{$key}->{name};
- return $key if COLUMNS->{$key}->{name} eq $column;
+ my $date = str2time($str);
+ if (!defined($date)) {
+ ThrowUserError("illegal_date", { date => $str });
}
-
- return $column;
+ return time2str("%Y-%m-%d %H:%M:%S", $date);
}
-#####################################################################
-# Search Functions
-#####################################################################
+######################################
+# "Special Parsing" Functions: Users #
+######################################
-sub _invalid_combination {
- my ($self, $args) = @_;
- my ($field, $operator) = @$args{qw(field operator)};
- ThrowUserError('search_field_operator_invalid',
- { field => $field, operator => $operator });
+sub pronoun {
+ my ($noun, $user) = (@_);
+ if ($noun eq "%user%") {
+ if ($user->id) {
+ return $user->id;
+ } else {
+ ThrowUserError('login_required_for_pronoun');
+ }
+ }
+ if ($noun eq "%reporter%") {
+ return "bugs.reporter";
+ }
+ if ($noun eq "%assignee%") {
+ return "bugs.assigned_to";
+ }
+ if ($noun eq "%qacontact%") {
+ return "bugs.qa_contact";
+ }
+ return 0;
}
sub _contact_pronoun {
my ($self, $args) = @_;
- my ($value, $quoted) = @$args{qw(value quoted)};
+ my $value = $args->{value};
my $user = $self->_user;
if ($value =~ /^\%group/) {
@@ -1873,24 +1833,6 @@ sub _contact_exact_group {
}
}
-sub _contact_nonchanged {
- my ($self, $args) = @_;
- my $field = $args->{field};
-
- $args->{full_field} = "profiles.login_name";
- $self->_do_operator_function($args);
- my $term = $args->{term};
- $args->{term} = "bugs.$field IN (SELECT userid FROM profiles WHERE $term)";
-}
-
-sub _qa_contact_nonchanged {
- my ($self, $args) = @_;
-
- # This will join in map_qa_contact for us.
- $self->_add_extra_column('qa_contact');
- $args->{full_field} = "COALESCE(map_qa_contact.login_name,'')";
-}
-
sub _cc_pronoun {
my ($self, $args) = @_;
my ($full_field, $value) = @$args{qw(full_field value)};
@@ -1945,6 +1887,48 @@ sub _cc_exact_group {
}
}
+# XXX This should probably be merged with cc_pronoun.
+sub _commenter_pronoun {
+ my ($self, $args) = @_;
+ my $value = $args->{value};
+ my $user = $self->_user;
+
+ if ($value =~ /^(%\w+%)$/) {
+ $args->{value} = pronoun($1, $user);
+ $args->{quoted} = $args->{value};
+ $args->{full_field} = "profiles.userid";
+ }
+}
+
+#####################################################################
+# Search Functions
+#####################################################################
+
+sub _invalid_combination {
+ my ($self, $args) = @_;
+ my ($field, $operator) = @$args{qw(field operator)};
+ ThrowUserError('search_field_operator_invalid',
+ { field => $field, operator => $operator });
+}
+
+sub _contact_nonchanged {
+ my ($self, $args) = @_;
+ my $field = $args->{field};
+
+ $args->{full_field} = "profiles.login_name";
+ $self->_do_operator_function($args);
+ my $term = $args->{term};
+ $args->{term} = "bugs.$field IN (SELECT userid FROM profiles WHERE $term)";
+}
+
+sub _qa_contact_nonchanged {
+ my ($self, $args) = @_;
+
+ # This will join in map_qa_contact for us.
+ $self->_add_extra_column('qa_contact');
+ $args->{full_field} = "COALESCE(map_qa_contact.login_name,'')";
+}
+
sub _cc_nonchanged {
my ($self, $args) = @_;
my ($chart_id, $sequence, $field, $full_field, $operator, $joins) =
@@ -2053,30 +2037,6 @@ sub _content_matches {
COLUMNS->{'relevance'}->{name} = $select_term;
}
-sub _timestamp_translate {
- my ($self, $args) = @_;
- my $value = $args->{value};
- my $dbh = Bugzilla->dbh;
-
- return if $value !~ /^[\+\-]?\d+[hdwmy]$/i;
-
- $args->{value} = SqlifyDate($value);
- $args->{quoted} = $dbh->quote($args->{value});
-}
-
-# XXX This should probably be merged with cc_pronoun.
-sub _commenter_pronoun {
- my ($self, $args) = @_;
- my $value = $args->{value};
- my $user = $self->_user;
-
- if ($value =~ /^(%\w+%)$/) {
- $args->{value} = pronoun($1, $user);
- $args->{quoted} = $args->{value};
- $args->{full_field} = "profiles.userid";
- }
-}
-
sub _commenter {
my ($self, $args) = @_;
my ($chart_id, $sequence, $joins, $field, $full_field, $operator) =
@@ -2824,4 +2784,51 @@ sub _changedby {
$args->{term} = "$table.bug_when IS NOT NULL";
}
+######################
+# Public Subroutines #
+######################
+
+# Validate that the query type is one we can deal with
+sub IsValidQueryType
+{
+ my ($queryType) = @_;
+ if (grep { $_ eq $queryType } qw(specific advanced)) {
+ return 1;
+ }
+ return 0;
+}
+
+# Splits out "asc|desc" from a sort order item.
+sub split_order_term {
+ my $fragment = shift;
+ $fragment =~ /^(.+?)(?:\s+(ASC|DESC))?$/i;
+ my ($column_name, $direction) = (lc($1), uc($2 || ''));
+ return wantarray ? ($column_name, $direction) : $column_name;
+}
+
+# Used to translate old SQL fragments from buglist.cgi's "order" argument
+# into our modern field IDs.
+sub translate_old_column {
+ my ($column) = @_;
+ # All old SQL fragments have a period in them somewhere.
+ return $column if $column !~ /\./;
+
+ if ($column =~ /\bAS\s+(\w+)$/i) {
+ return $1;
+ }
+ # product, component, classification, assigned_to, qa_contact, reporter
+ elsif ($column =~ /map_(\w+?)s?\.(login_)?name/i) {
+ return $1;
+ }
+
+ # If it doesn't match the regexps above, check to see if the old
+ # SQL fragment matches the SQL of an existing column
+ foreach my $key (%{ COLUMNS() }) {
+ next unless exists COLUMNS->{$key}->{name};
+ return $key if COLUMNS->{$key}->{name} eq $column;
+ }
+
+ return $column;
+}
+
1;