diff options
author | ivan <ivan> | 2004-03-11 02:05:38 +0000 |
---|---|---|
committer | ivan <ivan> | 2004-03-11 02:05:38 +0000 |
commit | 289340780927b5bac2c7604d7317c3063c6dd8cc (patch) | |
tree | c4100ab9857ae00c330213af8a46e66c208580e6 /rt/lib/RT/Tickets_Overlay_SQL.pm | |
parent | 945721f48f74d5cfffef7c7cf3a3d6bc2521f5dd (diff) |
import of rt 3.0.9RT_3_0_9
Diffstat (limited to 'rt/lib/RT/Tickets_Overlay_SQL.pm')
-rw-r--r-- | rt/lib/RT/Tickets_Overlay_SQL.pm | 95 |
1 files changed, 80 insertions, 15 deletions
diff --git a/rt/lib/RT/Tickets_Overlay_SQL.pm b/rt/lib/RT/Tickets_Overlay_SQL.pm index d78a56db3..629e6da2d 100644 --- a/rt/lib/RT/Tickets_Overlay_SQL.pm +++ b/rt/lib/RT/Tickets_Overlay_SQL.pm @@ -29,6 +29,10 @@ use warnings; my %FIELDS = %{FIELDS()}; my %dispatch = %{dispatch()}; +my %can_bundle = %{can_bundle()}; + +# Lower Case version of FIELDS, for case insensitivity +my %lcfields = map { ( lc($_) => $_ ) } (keys %FIELDS); sub _InitSQL { my $self = shift; @@ -119,20 +123,57 @@ my $re_keyword = qr[$RE{delimited}{-delim=>qq{\'\"}}|(?:\{|\}|\w|\.)+]; my $re_op = qr[=|!=|>=|<=|>|<|(?i:IS NOT)|(?i:IS)|(?i:NOT LIKE)|(?i:LIKE)]; # long to short my $re_paren = qr'\(|\)'; +sub _close_bundle +{ + my ($self, @bundle) = @_; + return unless @bundle; + if (@bundle == 1) { + $bundle[0]->{dispatch}->( + $self, + $bundle[0]->{key}, + $bundle[0]->{op}, + $bundle[0]->{val}, + SUBCLAUSE => "", + ENTRYAGGREGATOR => $bundle[0]->{ea}, + SUBKEY => $bundle[0]->{subkey}, + ); + } else { + my @args; + for my $chunk (@bundle) { + push @args, [ + $chunk->{key}, + $chunk->{op}, + $chunk->{val}, + SUBCLAUSE => "", + ENTRYAGGREGATOR => $chunk->{ea}, + SUBKEY => $chunk->{subkey}, + ]; + } + $bundle[0]->{dispatch}->( + $self, \@args, + ); + } +} + sub _parser { my ($self,$string) = @_; my $want = KEYWORD | PAREN; my $last = undef; my $depth = 0; + my @bundle; my ($ea,$key,$op,$value) = ("","","",""); + # order of matches in the RE is important.. op should come early, + # because it has spaces in it. otherwise "NOT LIKE" might be parsed + # as a keyword or value. + while ($string =~ /( $re_aggreg + |$re_op |$re_keyword |$re_value - |$re_op |$re_paren )/igx ) { my $val = $1; @@ -156,10 +197,12 @@ sub _parser { # Parens are highest priority if ($current & PAREN) { if ($val eq "(") { + $self->_close_bundle(@bundle); @bundle = (); $depth++; $self->_OpenParen; } else { + $self->_close_bundle(@bundle); @bundle = (); $depth--; $self->_CloseParen; } @@ -204,10 +247,9 @@ sub _parser { } my $class; - my ($stdkey) = grep { /^$key$/i } (keys %FIELDS); - if ($stdkey && exists $FIELDS{$stdkey}) { + if (exists $lcfields{lc $key}) { + $key = $lcfields{lc $key}; $class = $FIELDS{$key}->[0]; - $key = $stdkey; } # no longer have a default, since CF's are now a real class, not fallthrough # fixme: "default class" is not Generic. @@ -219,20 +261,37 @@ sub _parser { die "No such dispatch method: $class" unless exists $dispatch{$class}; my $sub = $dispatch{$class} || die;; - $sub->( - $self, - $key, - $op, - $val, - SUBCLAUSE => "", # don't need anymore - ENTRYAGGREGATOR => $ea || "", - SUBKEY => $subkey, - ); + if ($can_bundle{$class} && + (!@bundle || + ($bundle[-1]->{dispatch} == $sub && + $bundle[-1]->{key} eq $key && + $bundle[-1]->{subkey} eq $subkey))) + { + push @bundle, { + dispatch => $sub, + key => $key, + op => $op, + val => $val, + ea => $ea || "", + subkey => $subkey, + }; + } else { + $self->_close_bundle(@bundle); @bundle = (); + $sub->( + $self, + $key, + $op, + $val, + SUBCLAUSE => "", # don't need anymore + ENTRYAGGREGATOR => $ea || "", + SUBKEY => $subkey, + ); + } $self->{_sql_looking_at}{lc $key} = 1; - + ($ea,$key,$op,$value) = ("","","",""); - + $want = PAREN | AGGREG; } else { die "I'm lost"; @@ -241,6 +300,8 @@ sub _parser { $last = $current; } # while + $self->_close_bundle(@bundle); @bundle = (); + die "Incomplete query" unless (($want | PAREN) || ($want | KEYWORD)); @@ -330,6 +391,10 @@ sub FromSQL { VALUE => 'ticket'); } + # We never ever want to show deleted tickets + $self->SUPER::Limit(FIELD => 'Status' , OPERATOR => '!=', VALUE => 'deleted'); + + # set SB's dirty flag $self->{'must_redo_search'} = 1; $self->{'RecalcTicketLimits'} = 0; |