[Rt-commit] r2663 - in rt/branches/PLATANO-EXPERIMENTAL: . html/Search/Elements lib/RT lib/t/regression

jesse at bestpractical.com jesse at bestpractical.com
Sat Apr 16 02:45:58 EDT 2005


Author: jesse
Date: Sat Apr 16 02:45:58 2005
New Revision: 2663

Added:
   rt/branches/PLATANO-EXPERIMENTAL/lib/t/regression/20-sort-by-requestor.t
Modified:
   rt/branches/PLATANO-EXPERIMENTAL/   (props changed)
   rt/branches/PLATANO-EXPERIMENTAL/html/Search/Elements/DisplayOptions
   rt/branches/PLATANO-EXPERIMENTAL/lib/RT/Tickets_Overlay.pm
   rt/branches/PLATANO-EXPERIMENTAL/lib/RT/Tickets_Overlay_SQL.pm
Log:
 r13001 at hualien:  jesse | 2005-04-16 02:26:39 -0400
  r11663 at hualien:  jesse | 2005-04-03 05:11:09 -0400
  * Added support for sort by requestor/watcher
 


Modified: rt/branches/PLATANO-EXPERIMENTAL/html/Search/Elements/DisplayOptions
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL/html/Search/Elements/DisplayOptions	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL/html/Search/Elements/DisplayOptions	Sat Apr 16 02:45:58 2005
@@ -98,6 +98,7 @@
 my %fields = %{$tickets->FIELDS};
 map { $fields{$_}->[0] =~ /^(?:ENUM|INT|DATE|STRING)$/ || delete $fields{$_} } keys %fields;
 delete $fields{'EffectiveId'};
+$fields{ $_ . '.EmailAddress' } = 1 foreach( qw(Requestor Cc AdminCc) );
 
 
 </%INIT>

Modified: rt/branches/PLATANO-EXPERIMENTAL/lib/RT/Tickets_Overlay.pm
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL/lib/RT/Tickets_Overlay.pm	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL/lib/RT/Tickets_Overlay.pm	Sat Apr 16 02:45:58 2005
@@ -91,6 +91,7 @@
 no warnings qw(redefine);
 use vars qw(@SORTFIELDS);
 use RT::CustomFields;
+use DBIx::SearchBuilder::Unique;
 
 # Configuration Tables:
 
@@ -775,41 +776,7 @@
     my $meta = $FIELDS{$fieldname};
     my $type = ( defined $meta->[1] ? $meta->[1] : undef );
 
-# We only want _one_ clause for all of requestors, cc, admincc
-# It's less flexible than what we used to do, but now it sort of actually works. (no huge cartesian products that hose the db)
-    my $groups = $self->{ 'watcherlimit_' . ('global') . "_groups" } ||=
-      $self->NewAlias('Groups');
-    my $groupmembers =
-      $self->{ 'watcherlimit_' . ('global') . "_groupmembers" } ||=
-      $self->NewAlias('CachedGroupMembers');
-    my $users = $self->{ 'watcherlimit_' . ('global') . "_users" } ||=
-      $self->NewAlias('Users');
-
-# Use regular joins instead of SQL joins since we don't want the joins inside ticketsql or we get a huge cartesian product
-    $self->SUPER::Limit(
-        ALIAS           => $groups,
-        FIELD           => 'Domain',
-        VALUE           => 'RT::Ticket-Role',
-        ENTRYAGGREGATOR => 'AND'
-    );
-    $self->Join(
-        ALIAS1 => $groups,
-        FIELD1 => 'Instance',
-        ALIAS2 => 'main',
-        FIELD2 => 'id'
-    );
-    $self->Join(
-        ALIAS1 => $groups,
-        FIELD1 => 'id',
-        ALIAS2 => $groupmembers,
-        FIELD2 => 'GroupId'
-    );
-    $self->Join(
-        ALIAS1 => $groupmembers,
-        FIELD1 => 'MemberId',
-        ALIAS2 => $users,
-        FIELD2 => 'id'
-    );
+    my $users = $self->_WatcherJoin($type);
 
     # If we're looking for multiple watchers of a given type,
     # TicketSQL will be handing it to us as an array of clauses in
@@ -840,15 +807,60 @@
         );
     }
 
-    $self->_SQLLimit(
+    $self->_CloseParen;
+}
+
+=head2 _WatcherJoin
+
+Helper function which provides joins to a watchers table both for limits
+and for ordering.
+
+=cut
+
+sub _WatcherJoin {
+    my $self  = shift;
+    my $type  = shift;
+    my $key   = shift || "limit";
+    my $groups = $self->{ 'alias_' . $key . "_groups" } ||=
+      $self->NewAlias('Groups');
+    my $groupmembers =
+      $self->{ 'alias_' . $key . "_groupmembers" } ||=
+      $self->NewAlias('CachedGroupMembers');
+    my $users = $self->{ 'alias_' . $key . "_users" } ||=
+      $self->NewAlias('Users');
+
+    $self->SUPER::Limit(
+        ALIAS           => $groups,
+        FIELD           => 'Domain',
+        VALUE           => 'RT::Ticket-Role',
+        ENTRYAGGREGATOR => 'AND'
+    );
+    $self->Join(
+        ALIAS1 => $groups,
+        FIELD1 => 'Instance',
+        ALIAS2 => 'main',
+        FIELD2 => 'id'
+    );
+    $self->Join(
+        ALIAS1 => $groups,
+        FIELD1 => 'id',
+        ALIAS2 => $groupmembers,
+        FIELD2 => 'GroupId'
+    );
+    $self->Join(
+        ALIAS1 => $groupmembers,
+        FIELD1 => 'MemberId',
+        ALIAS2 => $users,
+        FIELD2 => 'id'
+    );
+    $self->SUPER::Limit(
         ALIAS           => $groups,
         FIELD           => 'Type',
         VALUE           => $type,
         ENTRYAGGREGATOR => 'AND'
       )
       if ($type);
-
-    $self->_CloseParen;
+    return $users;
 }
 
 =head2 _WatcherMembershipLimit
@@ -1190,6 +1202,41 @@
 
 # End of SQL Stuff -------------------------------------------------
 
+# {{{ Allow sorting on watchers
+
+=head2 OrderByCols ARRAY
+
+A modified version of the OrderBy method which automatically joins where
+C<ALIAS> is set to the name of a watcher type.
+
+=cut
+
+sub OrderByCols {
+    my $self = shift;
+    my @args = @_;
+    my $clause;
+    my @res = ();
+    my $order = 0;
+
+   foreach my $row( @args ) {
+       if( $row->{ALIAS} || $row->{FIELD} !~ /\./ ) {
+           push @res, $row;
+           next;
+       }
+       my ($field, $subkey) = split /\./, $row->{FIELD};
+       my $meta = $self->FIELDS->{ $field };
+       if( $meta->[0] eq 'WATCHERFIELD' ) {
+           my $users = $self->_WatcherJoin( $meta->[1], "order".$order++ );
+           push @res, { %$row, ALIAS => $users, FIELD => $subkey };
+       } else {
+           push @res, $row;
+       }
+   }
+   return $self->SUPER::OrderByCols( @res );
+}
+
+# }}}
+
 # {{{ Limit the result set based on content
 
 # {{{ sub Limit

Modified: rt/branches/PLATANO-EXPERIMENTAL/lib/RT/Tickets_Overlay_SQL.pm
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL/lib/RT/Tickets_Overlay_SQL.pm	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL/lib/RT/Tickets_Overlay_SQL.pm	Sat Apr 16 02:45:58 2005
@@ -443,7 +443,7 @@
     push @expectedids, $tick->Id;
 }
 ok (eq_array(\@ids, \@expectedids), "returned expected tickets");
-
+#
 $query = ("id = $ids[0] OR MemberOf = $ids[0]");
 
 my ($id, $msg) = $tix->FromSQL($query);
@@ -452,12 +452,15 @@
 
 is ($tix->Count, scalar @ids, "number of returned tickets same as entered");
 
+my ($id, $msg) = $tix->FromSQL($query);
 @expectedids = ();
+
+
 while (my $tick = $tix->Next) {
     push @expectedids, $tick->Id;
 }
 
-ok (eq_array(\@ids, \@expectedids), "returned expected tickets");
+ok (eq_array(\@ids, \@expectedids), "returned expected tickets". join(",", at ids) . "==".join(",", at expectedids));
 
 =end testing
 

Added: rt/branches/PLATANO-EXPERIMENTAL/lib/t/regression/20-sort-by-requestor.t
==============================================================================
--- (empty file)
+++ rt/branches/PLATANO-EXPERIMENTAL/lib/t/regression/20-sort-by-requestor.t	Sat Apr 16 02:45:58 2005
@@ -0,0 +1,63 @@
+#!/usr/bin/perl -w
+use strict; use warnings;
+
+use Test::More qw/no_plan/;
+use_ok('RT');
+RT::LoadConfig();
+RT::Init();
+use RT::Ticket;
+
+my $q = RT::Queue->new($RT::SystemUser);
+my $queue = 'SearchTests-'.rand(200);
+$q->Create(Name => $queue);
+
+my @requestors = ( ('bravo at example.com') x 5, ('alpha at example.com') x 5,
+                   ('delta at example.com') x 5, ('charlie at example.com') x 5);
+my @subjects = ("first test", "second test", "third test", "fourth test") x 5;
+while (@requestors) {
+    my $t = RT::Ticket->new($RT::SystemUser);
+    my ( $id, undef $msg ) = $t->Create(
+        Queue      => $q->id,
+        Subject    => shift @subjects,
+        Requestor => [ shift @requestors ]
+    );
+    ok( $id, $msg );
+}
+
+{
+    my $tix = RT::Tickets->new($RT::SystemUser);
+    $tix->FromSQL("Queue = '$queue'");
+    is($tix->Count, 20, "found twenty tickets");
+}
+
+{
+    my $tix = RT::Tickets->new($RT::SystemUser);
+    $tix->FromSQL("Queue = '$queue' AND requestor = 'alpha\@example.com'");
+    $tix->OrderByCols({ FIELD => "Subject" });
+    my @subjects;
+    while (my $t = $tix->Next) { push @subjects, $t->Subject; }
+    is(@subjects, 5, "found five tickets");
+    is_deeply( \@subjects, [ sort @subjects ], "Subjects are sorted");
+}
+
+{
+    my $tix = RT::Tickets->new($RT::SystemUser);
+    $tix->FromSQL("Queue = '$queue' AND subject = 'first test' AND Requestor.EmailAddress LIKE 'example.com'");
+    $tix->OrderByCols({ FIELD => "Requestor.EmailAddress" });
+    my @mails;
+    while (my $t = $tix->Next) { push @mails, $t->RequestorAddresses; }
+    is(@mails, 5, "found five tickets");
+    is_deeply( \@mails, [ sort @mails ], "Addresses are sorted");
+}
+
+{
+    my $tix = RT::Tickets->new($RT::SystemUser);
+    $tix->FromSQL("Queue = '$queue' AND subject = 'first test'");
+    $tix->OrderByCols({ FIELD => "Requestor.EmailAddress" });
+    my @mails;
+    while (my $t = $tix->Next) { push @mails, $t->RequestorAddresses; }
+    is(@mails, 5, "found five tickets");
+    is_deeply( \@mails, [ sort @mails ], "Addresses are sorted");
+}
+
+# vim:ft=perl:


More information about the Rt-commit mailing list