Search updates


#1

these changes:

fix bug #46: If we search for Keyword != value, any tickets which don’t
have a keyword set for that select aren’t found

fix searching for multiple keywords

allow you to search for tickets that don’t have a keyword for a given
selection, or tickets that do have a keyword for a given selection.

allow you to search for tickets that do or don’t have a particular link
type linked to or from them. i.e. this will allow you to search
for tickets that don’t have any sub-tickets, or tickets that aren’t
sub-tickets of another ticket, or tickets that depend on other
tickets.

SearchBuilder.pm Fri Mar 16 04:41:29 2001
+++ …/…/…/work/DBIx/DBIx-SearchBuilder/SearchBuilder.pm Wed Mar 21 05:59:41 2001
@@ -78,6 +78,7 @@
$self->{‘order’} = “”;
$self->{‘alias_count’} = 0;
$self->{‘first_row’} = 0;

  • $self->{‘main_alias’} = ‘main’;
    delete $self->{‘items’} if ($self->{‘items’});
    delete $self->{‘subclauses’} if ($self->{‘subclauses’});
    delete $self->{‘restrictions’} if ($self->{‘restrictions’});
    @@ -101,7 +102,7 @@
    my ($QueryString, $Order);
  • $QueryString = "SELECT main.* FROM " . $self->_TableAliases;
  • $QueryString = "SELECT DISTINCT main.* FROM " . $self->_TableAliases;

    $QueryString .= $self->_WhereClause . " ". $self->{‘table_links’}. " "
    if ($self->_isLimited > 0);
    @@ -410,6 +411,7 @@
    TABLE => $self->{‘table’},
    FIELD => undef,
    VALUE => undef,

  •           QUOTE => 1,
              ALIAS => undef,
              ENTRYAGGREGATOR => 'or',
              OPERATOR => '=',
    

@@ -421,9 +423,9 @@
if ($args{‘FIELD’}) {
#If it’s a like, we supply the %s around the search term
if ($args{‘OPERATOR’} =~ /LIKE/) {

  •   $args{'VALUE'} = "%".$args{'VALUE'} ."%";
    
  • }
  •   $args{'VALUE'} = $self->_Handle->dbh->quote($args{'VALUE'});
    
  •       $args{'VALUE'} = "%".$args{'VALUE'} ."%";
    
  •   }
    
  •   $args{'VALUE'} = $self->_Handle->dbh->quote($args{'VALUE'}) if $args{QUOTE};
    

    }

    $Alias = $self->_GenericRestriction(%args);
    @@ -570,8 +572,10 @@
    sub _TableAliases {
    my $self = shift;

  • my $main_alias =

  •    ( exists($self->{'main_alias'}) && $self->{'main_alias'} ) || 'main';
    

    Set up the first alias. for the main table

  • my $compiled_aliases = $self->{‘table’}." main";
  • my $compiled_aliases = $self->{‘table’}." $main_alias";

    Go through all the other aliases we set up and build the compiled

    aliases string

Tickets.pm Wed Mar 21 06:02:40 2001
+++ …/…/…/…/…/work/rt/lib/RT/Tickets.pm Wed Mar 21 06:07:47 2001
@@ -53,7 +53,8 @@
ContentType => ‘TRANSFIELD’,
Watcher => ‘WATCHERFIELD’,
LinkedTo => ‘LINKFIELD’,

  •          Keyword => 'KEYWORDFIELD'
    
  •          Keyword => 'KEYWORDFIELD',
    
  •          IsLinked => 'ISLINKFIELD',
          );
    

}}}

@@ -607,7 +608,66 @@
);

}
+# }}}
+# {{{ LimitNotLinkedTo
+sub LimitNotLinkedTo {

  • my $self = shift;
  • my $type = shift;
  • $self->Limit( FIELD => ‘IsLinked’,
  •              LINKFIELD   => 'LocalBase',
    
  •              TYPE        => $type,
    
  •              OPERATOR    => 'IS',
    
  •              VALUE       => 'NULL',
    
  •              DESCRIPTION => "Not $type to any ticket",
    
  •           );
    

+}
+# }}}
+# {{{ LimitIsLinkedTo
+sub LimitIsLinkedTo {

  • my $self = shift;
  • my $type = shift;
  • $self->Limit( FIELD => ‘IsLinked’,
  •              LINKFIELD   => 'LocalBase',
    
  •              TYPE        => $type,
    
  •              OPERATOR    => 'IS NOT',
    
  •              VALUE       => 'NULL',
    
  •              DESCRIPTION => "Is $type another ticket",
    
  •           );
    

+}
+# }}}
+# {{{ LimitNotLinkedFrom
+sub LimitNotLinkedFrom {

  • my $self = shift;

  • my $type = shift;

  • $self->Limit( FIELD => ‘IsLinked’,

  •              LINKFIELD   => 'LocalTarget',
    
  •              TYPE        => $type,
    
  •              OPERATOR    => 'IS',
    
  •              VALUE       => 'NULL',
    
  •              DESCRIPTION => "No $type from any ticket",
    
  •           );
    

+}
+# }}}
+# {{{ LimitIsLinkedTo
+sub LimitIsLinkedFrom {

  • my $self = shift;
  • my $type = shift;
  • $self->Limit( FIELD => ‘IsLinked’,
  •              LINKFIELD   => 'LocalTarget',
    
  •             TYPE        => $type,
    
  •             OPERATOR    => 'IS NOT',
    
  •             VALUE       => 'NULL',
    
  •             DESCRIPTION => "Is $type another ticket",
    
  •           );
    

+}

}}}

}}}

@@ -643,7 +703,6 @@
$args{‘DESCRIPTION’} = $args{‘FIELD’} . " " .$args{‘OPERATOR’}. " “. $args{‘VALUE’} . " GMT”
}

  • print “Limiting “. join(’;’, %args) .”\n”;
    $self->Limit (%args);

}
@@ -704,17 +763,21 @@
OPERATOR => ‘=’,
DESCRIPTION => undef,
FIELD => ‘Keyword’,

  •            QUOTE => 1,
               @_
             );
    

    use RT::KeywordSelect;
    my $KeywordSelect = RT::KeywordSelect->new($self->CurrentUser);
    $KeywordSelect->Load($args{KEYWORDSELECT});

  • use RT::Keyword;
  • my $Keyword = RT::Keyword->new($self->CurrentUser);
  • $Keyword->Load($args{KEYWORD});
  • $args{‘DESCRIPTION’} ||= $KeywordSelect->Name. " $args{OPERATOR} ". $Keyword->Name;
  • if ($args{QUOTE}) {
  •  use RT::Keyword;
    
  •  my $Keyword = RT::Keyword->new($self->CurrentUser);
    
  •  $Keyword->Load($args{KEYWORD});
    
  •  $args{'DESCRIPTION'} ||= $KeywordSelect->Name. " $args{OPERATOR} ". $Keyword->Name;
    
  • } else {
  •  $args{'DESCRIPTION'} ||= $KeywordSelect->Name ." $args{OPERATOR} $args{KEYWORD}";
    
  • }
    my $index = $self->_NextIndex;
    %{$self->{‘TicketRestrictions’}{$index}} = %args;

@@ -904,6 +967,8 @@
#Blow away ticket aliases since we’ll need to regenerate them for a new search
delete $self->{‘TicketAliases’};

  • $self->{‘islink_alias_count’} = 0;
    my $row;
    foreach $row (keys %{$self->{‘TicketRestrictions’}}) {
    my $restriction = $self->{‘TicketRestrictions’}{$row};
    @@ -1062,6 +1127,36 @@
    }

    }}}

  •   # {{{ if it's the existance of a relationship that we're hunting for
    
  •   # Takes FIELD:     'IsLinked'
    
  •   #       LINKFIELD: 'LocalBase' or 'LocalTarget'
    
  •   #       TYPE:      'MemberOf' 'DependsOn' etc.
    
  •   #       OPERATOR:  'IS' (or = or != ?)
    
  •   #       VALUE:     'NULL' or 'NOT NULL' (or ticket id?)
    
  •   elsif ( $TYPES{$restriction->{'FIELD'}} eq 'ISLINKFIELD' ) {
    
  •        my $linkfield = $restriction->{'LINKFIELD'};
    
  •        my $type = $restriction->{'TYPE'};
    
  •        my $alias = 'Links'. '_'. $self->{'islink_alias_count'};
    
  •        $self->{'islink_alias_count'}++;
    
  •        $self->{'main_alias'} .= 
    
  •          " LEFT OUTER JOIN Links AS $alias".
    
  •          " ON main.id = $alias.$linkfield".
    
  •          " AND $alias.Type = ". $self->_Handle->dbh->quote($type). " ";
    
  •        $self->SUPER::Limit(
    
  •                             FIELD => $linkfield,
    
  •                             VALUE => $restriction->{'VALUE'},
    
  •                             QUOTE => 0,
    
  •                             ALIAS => $alias,
    
  •                             ENTRYAGGREGATOR => 'AND',
    
  •                             OPERATOR => $restriction->{'OPERATOR'},
    
  •                           );
    
  •   }
    
  •   # }}}
      # {{{ if it's a watcher that we're hunting for
      elsif ($TYPES{$restriction->{'FIELD'}} eq 'WATCHERFIELD') {
          my $Watch = $self->NewAlias('Watchers');
    

@@ -1103,31 +1198,27 @@
# }}}
# {{{ keyword
elsif ($TYPES{$restriction->{‘FIELD’}} eq ‘KEYWORDFIELD’) {

  •        my $ObjKeywordsAlias = $self->NewAlias('ObjectKeywords');
    
  •        $self->Join(
    
  •                     ALIAS1 => 'main',
    
  •                     FIELD1 => 'id',
    
  •                     ALIAS2 => $ObjKeywordsAlias,
    
  •                     FIELD2 => 'ObjectId'
    
  •                   );
    
  •        my $alias;
    
  •        $alias = 'ObjectKeywords_'. $restriction->{'KEYWORDSELECT'};
    
  •        unless ( $self->{'TicketAliases'}{$alias} ) {
    
  •          $self->{'TicketAliases'}{$alias} = $alias;
    
  •          $self->{'main_alias'} .= 
    
  •            " LEFT OUTER JOIN ObjectKeywords AS $alias".
    
  •            " ON main.id = $alias.ObjectId".
    
  •            " AND $alias.KeywordSelect = ".
    
  •              $self->_Handle->dbh->quote($restriction->{'KEYWORDSELECT'}).
    
  •            " AND $alias.ObjectType = ".
    
  •              $self->_Handle->dbh->quote('Ticket'). " ";
    
  •        }
           $self->SUPER::Limit(
    
  •                             ALIAS => $ObjKeywordsAlias,
    
  •                             ALIAS => $alias,
                                FIELD => 'Keyword',
                                VALUE => $restriction->{'KEYWORD'},
                                OPERATOR => $restriction->{'OPERATOR'},
    
  •                             ENTRYAGGREGATOR => 'AND',
    
  •                           );
    
  •        $self->SUPER::Limit(
    
  •                             ALIAS => $ObjKeywordsAlias,
    
  •                             FIELD => 'KeywordSelect',
    
  •                             VALUE => $restriction->{'KEYWORDSELECT'},
    
  •                             ENTRYAGGREGATOR => 'AND',
    
  •                           );
    
  •        $self->SUPER::Limit(
    
  •                             ALIAS => $ObjKeywordsAlias,
    
  •                             FIELD => 'ObjectType',
    
  •                             VALUE => 'Ticket',
    
  •                             ENTRYAGGREGATOR => 'AND',
    
  •                             QUOTE => $restriction->{'QUOTE'},
    
  •                             ENTRYAGGREGATOR => 'OR',
                              );
       }
       # }}}
    

Web.pm Mon Mar 19 22:55:27 2001
+++ …/…/…/…/…/…/work/rt/lib/RT/Interface/Web.pm Wed Mar 21 05:38:55 2001
@@ -328,16 +379,57 @@
my $oper = $args{ARGS}->{“KeywordSelectOp$KeywordSelectId”};
foreach my $KeywordId ( ref($form) ? @{ $form } : ( $form ) ) {
if ($KeywordId) {

  •         my $description = '';
    
  •         my $quote = 1;
    
  •         if ( $KeywordId eq 'NULL' ) {
    
  •           $quote = 0;
    
  •           use RT::KeywordSelect;
    
  •            my $KeywordSelect = RT::KeywordSelect->new($session{'CurrentUser'});
    
  •            $KeywordSelect->Load($KeywordSelectId);
    
  •           if ( $oper eq '=' ) {
    
  •             $oper = 'IS';
    
  •             $description = $KeywordSelect->Name. " has no selection";
    
  •           } elsif ( $oper eq '!=' ) {
    
  •             $oper = 'IS NOT';
    
  •             $description = $KeywordSelect->Name. " has a selection";
    
  •           }
    
  •         }
            $session{'tickets'}->LimitKeyword(
                                              KEYWORDSELECT => $KeywordSelectId,
                                              OPERATOR => $oper,
                                              KEYWORD => $KeywordId,
    
  •                                           QUOTE => $quote,
    
  •                                           DESCRIPTION => $description,
                                             );
    
  •         if ( $oper eq '!=' ) {
    
  •           $session{'tickets'}->LimitKeyword(
    
  •                                             KEYWORDSELECT => $KeywordSelectId,
    
  •                                             OPERATOR => 'IS',
    
  •                                             KEYWORD => 'NULL',
    
  •                                             QUOTE => '0',
    
  •                                            );
    
  •         }
        }
     }
    

    }

    }}}

  • {{{ Limit IsLinks

  • if ($args{ARGS}->{‘IsLinkType’} ne ‘’) {

  •    my @errors;
    
  •    $args{ARGS}->{'IsLinkOp'} =~ /^(Is|Not)$/
    
  •      or push @errors, "Illegal IsLinkOp";
    
  •    my $method = "Limit$1";
    
  •    $args{ARGS}->{'IsLinkType'} =~ /^(\w+)$/
    
  •      or push @errors, "Illegal IsLinkType";
    
  •    my $type = $1;
    
  •    $args{ARGS}->{'IsLinkDirection'} =~ /^(From|To)$/
    
  •      or push @errors, "Illegal IsLinkDirection";
    
  •    $method .= "Linked$1"; 
    
  •    unless ( @errors ) {
    
  •      $session{'tickets'}->$method($type);
    
  •    } else { die join("\n", @errors); }
    
  • }

  • }}}

}

— PickRestriction Mon Mar 19 22:55:27 2001
+++ …/…/…/…/…/work/rt/webrt/Search/PickRestriction Wed Mar 21 06:20:46 2001
@@ -69,6 +69,23 @@
&>
% }

+

  • Ticket
    +<& /Elements/SelectBoolean, Name => “IsLinkOp”,
    •                        True     => "is",
      
    •                        False    => "is not",
      
    •                        TrueVal  => 'Is',
      
    •                        FalseVal => 'Not',
      
    •                        Default  => 'Not',
      

    +&>
    +<& /Elements/SelectLinkType, Name => “IsLinkType” &>
    +<& /Elements/SelectBoolean, Name => “IsLinkDirection”,

    •                        True     => "from other tickets",
      
    •                        False    => "to other tickets",
      
    •                        TrueVal  => "From",
      
    •                        FalseVal => "To",
      
    •                        Default  => 'To',
      

    +&>

    <& /Elements/TitleBoxEnd &>

    — SelectKeyword Thu Mar 8 09:59:38 2001
    +++ …/…/…/…/…/work/rt/webrt/Elements/SelectKeyword Wed Mar 21
    03:11:05 2001
    @@ -1,5 +1,6 @@
    <SELECT NAME=<%$Name%> <%$Size%> <%$Multiple%>>

    - +(NULL) % foreach my $kid ( keys %{$Descendents} ) { <OPTION VALUE="<% $kid %>" %if ($kid == $Default) {

    — SelectLinkType Fri May 19 05:42:45 2000
    +++ …/…/…/…/…/work/rt/webrt/Elements/SelectLinkType Thu Mar 8
    14:52:53 2001
    @@ -1,6 +1,7 @@
    %# $Header: /raid/cvsroot/rt/webrt/Elements/Attic/SelectLinkType,v
    1.1.2.1 2000/05/19 12:42:45 tobiasb Exp $

    +- % foreach ('MemberOf', 'DependsOn', 'RefersTo') { # TODO: Merging! <%$_%> % }

    meow
    _ivan


  • #2

    Integrating this is held up because of the Oracle broken-ness with
    DISTINCT?

    For now, i think we should just hack SearchBuilder.pm to not use DISTINCT
    with Oracle only, and eliminate duplicates using a hash of id numbers. As
    long as we don’t change behavior for mysql and Pg, I don’t see any reason
    not to do this.On Wed, Mar 21, 2001 at 06:23:43AM -0800, ivan wrote:

    these changes:

    fix bug #46: If we search for Keyword != value, any tickets which don’t
    have a keyword set for that select aren’t found

    fix searching for multiple keywords

    allow you to search for tickets that don’t have a keyword for a given
    selection, or tickets that do have a keyword for a given selection.

    allow you to search for tickets that do or don’t have a particular link
    type linked to or from them. i.e. this will allow you to search
    for tickets that don’t have any sub-tickets, or tickets that aren’t
    sub-tickets of another ticket, or tickets that depend on other
    tickets.

    SearchBuilder.pm Fri Mar 16 04:41:29 2001
    +++ …/…/…/work/DBIx/DBIx-SearchBuilder/SearchBuilder.pm Wed Mar 21 05:59:41 2001
    @@ -78,6 +78,7 @@
    $self->{‘order’} = “”;
    $self->{‘alias_count’} = 0;
    $self->{‘first_row’} = 0;

    • $self->{‘main_alias’} = ‘main’;
      delete $self->{‘items’} if ($self->{‘items’});
      delete $self->{‘subclauses’} if ($self->{‘subclauses’});
      delete $self->{‘restrictions’} if ($self->{‘restrictions’});
      @@ -101,7 +102,7 @@
      my ($QueryString, $Order);
    • $QueryString = "SELECT main.* FROM " . $self->_TableAliases;
    • $QueryString = "SELECT DISTINCT main.* FROM " . $self->_TableAliases;

      $QueryString .= $self->_WhereClause . " ". $self->{‘table_links’}. " "
      if ($self->_isLimited > 0);
      @@ -410,6 +411,7 @@
      TABLE => $self->{‘table’},
      FIELD => undef,
      VALUE => undef,

    •           QUOTE => 1,
                ALIAS => undef,
                ENTRYAGGREGATOR => 'or',
                OPERATOR => '=',
      

    @@ -421,9 +423,9 @@
    if ($args{‘FIELD’}) {
    #If it’s a like, we supply the %s around the search term
    if ($args{‘OPERATOR’} =~ /LIKE/) {

    •   $args{'VALUE'} = "%".$args{'VALUE'} ."%";
      
    • }
    •   $args{'VALUE'} = $self->_Handle->dbh->quote($args{'VALUE'});
      
    •       $args{'VALUE'} = "%".$args{'VALUE'} ."%";
      
    •   }
      
    •   $args{'VALUE'} = $self->_Handle->dbh->quote($args{'VALUE'}) if $args{QUOTE};
      

      }

      $Alias = $self->_GenericRestriction(%args);
      @@ -570,8 +572,10 @@
      sub _TableAliases {
      my $self = shift;

    • my $main_alias =

    •    ( exists($self->{'main_alias'}) && $self->{'main_alias'} ) || 'main';
      

      Set up the first alias. for the main table

    • my $compiled_aliases = $self->{‘table’}." main";
    • my $compiled_aliases = $self->{‘table’}." $main_alias";

      Go through all the other aliases we set up and build the compiled

      aliases string

    Tickets.pm Wed Mar 21 06:02:40 2001
    +++ …/…/…/…/…/work/rt/lib/RT/Tickets.pm Wed Mar 21 06:07:47 2001
    @@ -53,7 +53,8 @@
    ContentType => ‘TRANSFIELD’,
    Watcher => ‘WATCHERFIELD’,
    LinkedTo => ‘LINKFIELD’,

    •          Keyword => 'KEYWORDFIELD'
      
    •          Keyword => 'KEYWORDFIELD',
      
    •          IsLinked => 'ISLINKFIELD',
            );
      

    }}}

    @@ -607,7 +608,66 @@
    );

    }
    +# }}}
    +
    +# {{{ LimitNotLinkedTo
    +sub LimitNotLinkedTo {

    • my $self = shift;
    • my $type = shift;
    • $self->Limit( FIELD => ‘IsLinked’,
    •              LINKFIELD   => 'LocalBase',
      
    •              TYPE        => $type,
      
    •              OPERATOR    => 'IS',
      
    •              VALUE       => 'NULL',
      
    •              DESCRIPTION => "Not $type to any ticket",
      
    •           );
      

    +}
    +# }}}
    +
    +# {{{ LimitIsLinkedTo
    +sub LimitIsLinkedTo {

    • my $self = shift;
    • my $type = shift;
    • $self->Limit( FIELD => ‘IsLinked’,
    •              LINKFIELD   => 'LocalBase',
      
    •              TYPE        => $type,
      
    •              OPERATOR    => 'IS NOT',
      
    •              VALUE       => 'NULL',
      
    •              DESCRIPTION => "Is $type another ticket",
      
    •           );
      

    +}
    +# }}}
    +
    +# {{{ LimitNotLinkedFrom
    +sub LimitNotLinkedFrom {

    • my $self = shift;

    • my $type = shift;

    • $self->Limit( FIELD => ‘IsLinked’,

    •              LINKFIELD   => 'LocalTarget',
      
    •              TYPE        => $type,
      
    •              OPERATOR    => 'IS',
      
    •              VALUE       => 'NULL',
      
    •              DESCRIPTION => "No $type from any ticket",
      
    •           );
      

    +}
    +# }}}
    +
    +# {{{ LimitIsLinkedTo
    +sub LimitIsLinkedFrom {

    • my $self = shift;
    • my $type = shift;
    • $self->Limit( FIELD => ‘IsLinked’,
    •              LINKFIELD   => 'LocalTarget',
      
    •             TYPE        => $type,
      
    •             OPERATOR    => 'IS NOT',
      
    •             VALUE       => 'NULL',
      
    •             DESCRIPTION => "Is $type another ticket",
      
    •           );
      

    +}

    }}}

    }}}

    @@ -643,7 +703,6 @@
    $args{‘DESCRIPTION’} = $args{‘FIELD’} . " " .$args{‘OPERATOR’}. " “. $args{‘VALUE’} . " GMT”
    }

    • print “Limiting “. join(’;’, %args) .”\n”;
      $self->Limit (%args);

    }
    @@ -704,17 +763,21 @@
    OPERATOR => ‘=’,
    DESCRIPTION => undef,
    FIELD => ‘Keyword’,

    •            QUOTE => 1,
                 @_
               );
      

      use RT::KeywordSelect;
      my $KeywordSelect = RT::KeywordSelect->new($self->CurrentUser);
      $KeywordSelect->Load($args{KEYWORDSELECT});

    • use RT::Keyword;
    • my $Keyword = RT::Keyword->new($self->CurrentUser);
    • $Keyword->Load($args{KEYWORD});
    • $args{‘DESCRIPTION’} ||= $KeywordSelect->Name. " $args{OPERATOR} ". $Keyword->Name;
    • if ($args{QUOTE}) {
    •  use RT::Keyword;
      
    •  my $Keyword = RT::Keyword->new($self->CurrentUser);
      
    •  $Keyword->Load($args{KEYWORD});
      
    •  $args{'DESCRIPTION'} ||= $KeywordSelect->Name. " $args{OPERATOR} ". $Keyword->Name;
      
    • } else {
    •  $args{'DESCRIPTION'} ||= $KeywordSelect->Name ." $args{OPERATOR} $args{KEYWORD}";
      
    • }
      my $index = $self->_NextIndex;
      %{$self->{‘TicketRestrictions’}{$index}} = %args;

    @@ -904,6 +967,8 @@
    #Blow away ticket aliases since we’ll need to regenerate them for a new search
    delete $self->{‘TicketAliases’};

    • $self->{‘islink_alias_count’} = 0;

    • my $row;
      foreach $row (keys %{$self->{‘TicketRestrictions’}}) {
      my $restriction = $self->{‘TicketRestrictions’}{$row};
      @@ -1062,6 +1127,36 @@
      }

        # }}}
      
    •   # {{{ if it's the existance of a relationship that we're hunting for
      
    •   # Takes FIELD:     'IsLinked'
      
    •   #       LINKFIELD: 'LocalBase' or 'LocalTarget'
      
    •   #       TYPE:      'MemberOf' 'DependsOn' etc.
      
    •   #       OPERATOR:  'IS' (or = or != ?)
      
    •   #       VALUE:     'NULL' or 'NOT NULL' (or ticket id?)
      
    •   elsif ( $TYPES{$restriction->{'FIELD'}} eq 'ISLINKFIELD' ) {
      
    •        my $linkfield = $restriction->{'LINKFIELD'};
      
    •        my $type = $restriction->{'TYPE'};
      
    •        my $alias = 'Links'. '_'. $self->{'islink_alias_count'};
      
    •        $self->{'islink_alias_count'}++;
      
    •        $self->{'main_alias'} .= 
      
    •          " LEFT OUTER JOIN Links AS $alias".
      
    •          " ON main.id = $alias.$linkfield".
      
    •          " AND $alias.Type = ". $self->_Handle->dbh->quote($type). " ";
      
    •        $self->SUPER::Limit(
      
    •                             FIELD => $linkfield,
      
    •                             VALUE => $restriction->{'VALUE'},
      
    •                             QUOTE => 0,
      
    •                             ALIAS => $alias,
      
    •                             ENTRYAGGREGATOR => 'AND',
      
    •                             OPERATOR => $restriction->{'OPERATOR'},
      
    •                           );
      
    •   }
      
    •   # }}}
        # {{{ if it's a watcher that we're hunting for
        elsif ($TYPES{$restriction->{'FIELD'}} eq 'WATCHERFIELD') {
            my $Watch = $self->NewAlias('Watchers');
      

    @@ -1103,31 +1198,27 @@
    # }}}
    # {{{ keyword
    elsif ($TYPES{$restriction->{‘FIELD’}} eq ‘KEYWORDFIELD’) {

    •        my $ObjKeywordsAlias = $self->NewAlias('ObjectKeywords');
      
    •        $self->Join(
      
    •                     ALIAS1 => 'main',
      
    •                     FIELD1 => 'id',
      
    •                     ALIAS2 => $ObjKeywordsAlias,
      
    •                     FIELD2 => 'ObjectId'
      
    •                   );
      
    •        my $alias;
      
    •        $alias = 'ObjectKeywords_'. $restriction->{'KEYWORDSELECT'};
      
    •        unless ( $self->{'TicketAliases'}{$alias} ) {
      
    •          $self->{'TicketAliases'}{$alias} = $alias;
      
    •          $self->{'main_alias'} .= 
      
    •            " LEFT OUTER JOIN ObjectKeywords AS $alias".
      
    •            " ON main.id = $alias.ObjectId".
      
    •            " AND $alias.KeywordSelect = ".
      
    •              $self->_Handle->dbh->quote($restriction->{'KEYWORDSELECT'}).
      
    •            " AND $alias.ObjectType = ".
      
    •              $self->_Handle->dbh->quote('Ticket'). " ";
      
    •        }
      
    •        $self->SUPER::Limit(
      
    •                             ALIAS => $ObjKeywordsAlias,
      
    •                             ALIAS => $alias,
                                  FIELD => 'Keyword',
                                  VALUE => $restriction->{'KEYWORD'},
                                  OPERATOR => $restriction->{'OPERATOR'},
      
    •                             ENTRYAGGREGATOR => 'AND',
      
    •                           );
      
    •        $self->SUPER::Limit(
      
    •                             ALIAS => $ObjKeywordsAlias,
      
    •                             FIELD => 'KeywordSelect',
      
    •                             VALUE => $restriction->{'KEYWORDSELECT'},
      
    •                             ENTRYAGGREGATOR => 'AND',
      
    •                           );
      
    •        $self->SUPER::Limit(
      
    •                             ALIAS => $ObjKeywordsAlias,
      
    •                             FIELD => 'ObjectType',
      
    •                             VALUE => 'Ticket',
      
    •                             ENTRYAGGREGATOR => 'AND',
      
    •                             QUOTE => $restriction->{'QUOTE'},
      
    •                             ENTRYAGGREGATOR => 'OR',
                                );
         }
         # }}}
      

    Web.pm Mon Mar 19 22:55:27 2001
    +++ …/…/…/…/…/…/work/rt/lib/RT/Interface/Web.pm Wed Mar 21 05:38:55 2001
    @@ -328,16 +379,57 @@
    my $oper = $args{ARGS}->{“KeywordSelectOp$KeywordSelectId”};
    foreach my $KeywordId ( ref($form) ? @{ $form } : ( $form ) ) {
    if ($KeywordId) {

    •         my $description = '';
      
    •         my $quote = 1;
      
    •         if ( $KeywordId eq 'NULL' ) {
      
    •           $quote = 0;
      
    •           use RT::KeywordSelect;
      
    •            my $KeywordSelect = RT::KeywordSelect->new($session{'CurrentUser'});
      
    •            $KeywordSelect->Load($KeywordSelectId);
      
    •           if ( $oper eq '=' ) {
      
    •             $oper = 'IS';
      
    •             $description = $KeywordSelect->Name. " has no selection";
      
    •           } elsif ( $oper eq '!=' ) {
      
    •             $oper = 'IS NOT';
      
    •             $description = $KeywordSelect->Name. " has a selection";
      
    •           }
      
    •         }
              $session{'tickets'}->LimitKeyword(
                                                KEYWORDSELECT => $KeywordSelectId,
                                                OPERATOR => $oper,
                                                KEYWORD => $KeywordId,
      
    •                                           QUOTE => $quote,
      
    •                                           DESCRIPTION => $description,
                                               );
      
    •         if ( $oper eq '!=' ) {
      
    •           $session{'tickets'}->LimitKeyword(
      
    •                                             KEYWORDSELECT => $KeywordSelectId,
      
    •                                             OPERATOR => 'IS',
      
    •                                             KEYWORD => 'NULL',
      
    •                                             QUOTE => '0',
      
    •                                            );
      
    •         }
          }
       }
      

      }

      }}}

    • {{{ Limit IsLinks

    • if ($args{ARGS}->{‘IsLinkType’} ne ‘’) {

    •    my @errors;
      
    •    $args{ARGS}->{'IsLinkOp'} =~ /^(Is|Not)$/
      
    •      or push @errors, "Illegal IsLinkOp";
      
    •    my $method = "Limit$1";
      
    •    $args{ARGS}->{'IsLinkType'} =~ /^(\w+)$/
      
    •      or push @errors, "Illegal IsLinkType";
      
    •    my $type = $1;
      
    •    $args{ARGS}->{'IsLinkDirection'} =~ /^(From|To)$/
      
    •      or push @errors, "Illegal IsLinkDirection";
      
    •    $method .= "Linked$1"; 
      
    •    unless ( @errors ) {
      
    •      $session{'tickets'}->$method($type);
      
    •    } else { die join("\n", @errors); }
      
    • }

    • }}}

    }

    — PickRestriction Mon Mar 19 22:55:27 2001
    +++ …/…/…/…/…/work/rt/webrt/Search/PickRestriction Wed Mar 21 06:20:46 2001
    @@ -69,6 +69,23 @@
    &>
    % }

    +

  • Ticket
    +<& /Elements/SelectBoolean, Name => “IsLinkOp”,
    •                        True     => "is",
      
    •                        False    => "is not",
      
    •                        TrueVal  => 'Is',
      
    •                        FalseVal => 'Not',
      
    •                        Default  => 'Not',
      

    +&>
    +<& /Elements/SelectLinkType, Name => “IsLinkType” &>
    +<& /Elements/SelectBoolean, Name => “IsLinkDirection”,

    •                        True     => "from other tickets",
      
    •                        False    => "to other tickets",
      
    •                        TrueVal  => "From",
      
    •                        FalseVal => "To",
      
    •                        Default  => 'To',
      

    +&>
    +

    <& /Elements/TitleBoxEnd &>

    — SelectKeyword Thu Mar 8 09:59:38 2001
    +++ …/…/…/…/…/work/rt/webrt/Elements/SelectKeyword Wed Mar 21
    03:11:05 2001
    @@ -1,5 +1,6 @@
    <SELECT NAME=<%$Name%> <%$Size%> <%$Multiple%>>

    - +(NULL) % foreach my $kid ( keys %{$Descendents} ) { <OPTION VALUE="<% $kid %>" %if ($kid == $Default) {

    — SelectLinkType Fri May 19 05:42:45 2000
    +++ …/…/…/…/…/work/rt/webrt/Elements/SelectLinkType Thu Mar 8
    14:52:53 2001
    @@ -1,6 +1,7 @@
    %# $Header: /raid/cvsroot/rt/webrt/Elements/Attic/SelectLinkType,v
    1.1.2.1 2000/05/19 12:42:45 tobiasb Exp $

    +- % foreach ('MemberOf', 'DependsOn', 'RefersTo') { # TODO: Merging! <%$_%> % }


    meow
    _ivan


    Rt-devel mailing list
    Rt-devel@lists.fsck.com
    http://lists.fsck.com/mailman/listinfo/rt-devel

  • meow
    _ivan