[Rt-devel] XMAS PATCH: LinkedTo searches fixed.

Todd Chapman todd at chaka.net
Fri Dec 23 14:44:24 EST 2005


Attached is a patch that fixes LinkedTo searches in
3.4.HEAD. It passes all regression tests, including a
bunch I added.

Mery Christmas everyone!

-Todd
-------------- next part --------------
==== Patch <LinkedTo> level 1
Source: 6fc35107-3207-0410-b21e-9a2d7f624572:/local/bp/rt/features/3.4_linkedto_fix:4607
Target: e417ac7c-1bcc-0310-8ffa-8f5827389a85:/rt/branches/3.4-RELEASE:4307
        (svn://svn.bestpractical.com)
Log:
 r4606 at slah001:  root | 2005-12-22 18:41:29 -0500
 Fixing LinkedTo searching
 r4607 at slah001:  root | 2005-12-23 15:02:40 -0500
 Fixed LinkedTo ticket searching.

=== lib/t/regression/01ticket_link_searching.t
==================================================================
--- lib/t/regression/01ticket_link_searching.t	(revision 4307)
+++ lib/t/regression/01ticket_link_searching.t	(patch LinkedTo level 1)
@@ -1,6 +1,6 @@
 #!/usr/bin/perl -w
 
-use Test::More tests => 25;
+use Test::More tests => 61;
 use strict;
 use RT;
 
@@ -24,26 +24,42 @@
 
 ok($childid != 0);
 
+my $child2_ticket = new RT::Ticket( $CurrentUser );
+
+my ( $child2id ) = $child2_ticket->Create
+    ( Subject => 'test child2',
+      Queue => $queue->Id);
+
+ok($child2id != 0);
+
 my $parent_ticket = new RT::Ticket( $CurrentUser );
 
 my ( $parentid ) = $parent_ticket->Create
     ( Subject => 'test parent',
-      Children => [$childid],
+      Children => [$childid, $child2id],
       Queue => $queue->Id);
 
 ok($parentid != 0, "We created a parent ticket");
 
+my $nolink_ticket = new RT::Ticket( $CurrentUser );
+my ( $nolinkid ) = $nolink_ticket->Create
+    ( Subject => 'test nolink',
+      Queue => $queue->Id);
+
+ok($nolinkid != 0, "We created a nolink ticket");
+
+
 my $Collection = RT::Tickets->new($CurrentUser);
 $Collection->LimitMemberOf ($parentid);
 
 ok ($Collection->First);
 is ($Collection->First->id, $childid, "We found the collection of all children of $parentid with Limit");
-is($Collection->Count,1, "We found only one result");
+is($Collection->Count,2, "We found only one result");
 
 $Collection = RT::Tickets->new($CurrentUser);
 $Collection->FromSQL( "MemberOf =  $parentid");
 is ($Collection->First->id, $childid, "We found the collection of all children of $parentid with TicketSQL");
-is($Collection->Count,1, "We found only one result");
+is($Collection->Count,2, "We found only one result");
 
 
 
@@ -76,7 +92,9 @@
     ++$has{$t->id};
 }
 ok ($has{$childid} , "The collection has our child - $childid");
+ok ($has{$child2id} , "The collection has our child2 - $child2id");
 ok( !$has{$parentid}, "The collection doesn't have our parent - $parentid");
+ok ($has{$nolinkid} , "The collection has our nolink - $nolinkid");
 
 
 
@@ -91,8 +109,9 @@
 }
 ok ($has{$parentid} , "The collection has our parent - $parentid");
 ok( !$has{$childid}, "The collection doesn't have our child - $childid");
+ok( !$has{$child2id}, "The collection doesn't have our child2 - $child2id");
+ok ($has{$nolinkid} , "The collection has our nolink - $nolinkid");
 
-
 #  Do it all over with TicketSQL
 #
 
@@ -108,6 +127,8 @@
 }
 ok (!$has{$parentid} , "The collection doesn't have our parent - $parentid");
 ok( $has{$childid}, "The collection has our child - $childid");
+ok( $has{$child2id}, "The collection has our child2 - $child2id");
+ok( $has{$nolinkid}, "The collection has our nolink - $nolinkid");
 
 
 # Now we find a collection of all the tickets which have no members. they should have no children.
@@ -121,6 +142,8 @@
 }
 ok (!$has{$parentid} , "The collection doesn't have our parent - $parentid");
 ok( $has{$childid}, "The collection has our child - $childid");
+ok( $has{$child2id}, "The collection has our child2 - $child2id");
+ok( $has{$nolinkid}, "The collection has our nolink - $nolinkid");
 
 
 
@@ -134,6 +157,8 @@
 }
 ok ($has{$parentid} , "The collection has our parent - $parentid");
 ok(!$has{$childid}, "The collection doesn't have our child - $childid");
+ok(!$has{$child2id}, "The collection doesn't have our child2 - $child2id");
+ok ($has{$nolinkid} , "The collection has our nolink - $nolinkid");
 
 
 # Now we find a collection of all the tickets which are not members of anything. they should have no parents.
@@ -146,10 +171,96 @@
 }
 ok ($has{$parentid} , "The collection has our parent - $parentid");
 ok(!$has{$childid}, "The collection doesn't have our child - $childid");
+ok(!$has{$child2id}, "The collection doesn't have our child2 - $child2id");
+ok ($has{$nolinkid} , "The collection has our nolink - $nolinkid");
 
 
+# Now we find a collection of all the tickets which are not linked to anything.
+$Collection = RT::Tickets->new($CurrentUser);
+$Collection->FromSQL("LinkedTo = ''");
+%has = ();
+while (my $t = $Collection->Next) {
+    ++$has{$t->id};
+}
+ok(!$has{$parentid} , "The collection doesn't have our parent - $parentid");
+ok(!$has{$childid}, "The collection doesn't have our component - $childid");
+ok(!$has{$child2id}, "The collection doesn't have our component - $child2id");
+ok( $has{$nolinkid}, "The collection has our component - $nolinkid");
 
+# Now we find a collection of all the tickets which are linked to $nolink_ticket.
+$Collection = RT::Tickets->new($CurrentUser);
+$Collection->FromSQL("LinkedTo = '" . $nolink_ticket->URI . "'");
+%has = ();
+while (my $t = $Collection->Next) {
+    ++$has{$t->id};
+}
+ok(! keys %has, "The collection has no members");
 
+# Now we find a collection of all the tickets which are linked to $nolink_ticket.
+# using id instead of URI
+$Collection = RT::Tickets->new($CurrentUser);
+$Collection->FromSQL("LinkedTo = '" . $nolinkid . "'");
+%has = ();
+while (my $t = $Collection->Next) {
+    ++$has{$t->id};
+}
+ok(! keys %has, "The collection has no members");
+
+
+# Now we find a collection of all the tickets which are linked to anything the child.
+$Collection = RT::Tickets->new($CurrentUser);
+$Collection->FromSQL("LinkedTo = '" . $child_ticket->URI . "'");
+%has = ();
+while (my $t = $Collection->Next) {
+    ++$has{$t->id};
+}
+ok( $has{$parentid} , "The collection has our parent - $parentid");
+ok(!$has{$childid}, "The collection doesn't have our component - $childid");
+ok(!$has{$child2id}, "The collection doesn't have our component - $child2id");
+ok(!$has{$nolinkid}, "The collection doesn't have our component - $nolinkid");
+
+# Now we find a collection of all the tickets which are linked to anything the child.
+# using id instead of URI
+$Collection = RT::Tickets->new($CurrentUser);
+$Collection->FromSQL("LinkedTo = '" . $childid . "'");
+%has = ();
+while (my $t = $Collection->Next) {
+    ++$has{$t->id};
+}
+ok( $has{$parentid} , "The collection has our parent - $parentid");
+ok(!$has{$childid}, "The collection doesn't have our component - $childid");
+ok(!$has{$child2id}, "The collection doesn't have our component - $child2id");
+ok(!$has{$nolinkid}, "The collection doesn't have our component - $nolinkid");
+
+
+# Now we find a collection of all the tickets which are linked to the parent.
+$Collection = RT::Tickets->new($CurrentUser);
+$Collection->FromSQL("LinkedTo = '" . $parent_ticket->URI . "'");
+%has = ();
+while (my $t = $Collection->Next) {
+    ++$has{$t->id};
+}
+ok(!$has{$parentid} , "The collection doesn't have our parent - $parentid");
+ok( $has{$childid}, "The collection has our component - $childid");
+ok( $has{$child2id}, "The collection has our component - $child2id");
+ok(!$has{$nolinkid}, "The collection doesn't have our component - $nolinkid");
+
+# Now we find a collection of all the tickets which are linked to the parent.
+# using id instead of URI
+$Collection = RT::Tickets->new($CurrentUser);
+$Collection->FromSQL("LinkedTo = '" . $parentid . "'");
+%has = ();
+while (my $t = $Collection->Next) {
+    ++$has{$t->id};
+}
+ok(!$has{$parentid} , "The collection doesn't have our parent - $parentid");
+ok( $has{$childid}, "The collection has our component - $childid");
+ok( $has{$child2id}, "The collection has our component - $child2id");
+ok(!$has{$nolinkid}, "The collection doesn't have our component - $nolinkid");
+
+
+
+
 1;
 
 
=== lib/RT/Tickets_Overlay.pm
==================================================================
--- lib/RT/Tickets_Overlay.pm	(revision 4307)
+++ lib/RT/Tickets_Overlay.pm	(patch LinkedTo level 1)
@@ -135,7 +135,7 @@
     Cc               => [ 'WATCHERFIELD'    => 'Cc', ],
     AdminCc          => [ 'WATCHERFIELD'    => 'AdminCc', ],
     Watcher          => ['WATCHERFIELD'],
-    LinkedTo         => [ 'LINKFIELD', ],
+    LinkedTo         => [ 'LINK' => From => 'LinkedTo', ],
     CustomFieldValue => [ 'CUSTOMFIELD', ],
     CF               => [ 'CUSTOMFIELD', ],
     Updated          => [ 'TRANSDATE', ],
@@ -377,6 +377,13 @@
             TABLE2 => 'Links',
             FIELD2 => 'Local' . $linkfield
         );
+        my $linkalias2 = $sb->Join(
+            TYPE   => 'left',
+            ALIAS1 => 'main',
+            FIELD1 => 'id',
+            TABLE2 => 'Links',
+            FIELD2 => 'Local' . $matchfield
+        ) if $meta->[2] eq 'LinkedTo';
 
         $sb->SUPER::Limit(
             LEFTJOIN => $linkalias,
@@ -384,8 +391,9 @@
             OPERATOR => '=',
             VALUE    => $meta->[2],
             @rest,
-        );
+        ) unless $meta->[2] eq 'LinkedTo';
 
+        $sb->_OpenParen();
         $sb->_SQLLimit(
             ALIAS           => $linkalias,
             ENTRYAGGREGATOR => 'AND',
@@ -394,6 +402,15 @@
             VALUE      => 'NULL',
             QUOTEVALUE => '0',
         );
+        $sb->_SQLLimit(
+            ALIAS           => $linkalias2,
+            ENTRYAGGREGATOR => 'AND',
+            FIELD           => ( $is_local ? "Local$linkfield" : $linkfield ),
+            OPERATOR        => 'IS',
+            VALUE           => 'NULL',
+            QUOTEVALUE      => '0',
+        ) if $meta->[2] eq 'LinkedTo';
+        $sb->_CloseParen();
 
     }
     else {
@@ -403,14 +420,25 @@
 
         $sb->_OpenParen();
 
+        # for non-NULL LinkedTo queries we don't want ourself
+        my ($id) = $value =~ m/(\d+)$/;
         $sb->_SQLLimit(
+            ALIAS    => 'main',
+            FIELD    => $sb->{'primary_key'},
+            OPERATOR => '!=',
+            VALUE    => $id,
+        ) if $meta->[2] eq 'LinkedTo';
+
+        # for LinkedTo queries we don't care about the link type
+        $sb->_SQLLimit(
             ALIAS    => $sb->{_sql_linkalias},
             FIELD    => 'Type',
             OPERATOR => '=',
             VALUE    => $meta->[2],
             @rest,
-        );
+        ) unless $meta->[2] eq 'LinkedTo';
 
+        $sb->_OpenParen();
         $sb->_SQLLimit(
             ALIAS           => $sb->{_sql_linkalias},
             ENTRYAGGREGATOR => 'AND',
@@ -418,7 +446,17 @@
             OPERATOR => '=',
             VALUE    => $value,
         );
+        # for LinkedTo queries we don't care which end of the link
+        $sb->_SQLLimit(
+            ALIAS           => $sb->{_sql_linkalias},
+            ENTRYAGGREGATOR => 'OR',
+            FIELD           => ( $is_local ? "Local$linkfield" : $linkfield ),
+            OPERATOR        => '=',
+            VALUE           => $value,
+        ) if $meta->[2] eq 'LinkedTo';
+        $sb->_CloseParen();
 
+        $sb->_OpenParen();
         #If we're searching on target, join the base to ticket.id
         $sb->_SQLJoin(
             ALIAS1 => 'main',
@@ -426,6 +464,16 @@
             ALIAS2 => $sb->{_sql_linkalias},
             FIELD2 => 'Local' . $linkfield
         );
+        # for LinkedTo queries we want to join on Base OR Target
+        $sb->_SQLLimit(
+            ENTRYAGGREGATOR => 'OR',
+            ALIAS           => $sb->{_sql_linkalias},
+            FIELD           => "Local$matchfield",
+            OPERATOR        => '=',
+            VALUE           => 'main.id',
+            QUOTEVALUE      => 0,
+        ) if $meta->[2] eq 'LinkedTo';
+        $sb->_CloseParen();
 
         $sb->_CloseParen();
     }

==== BEGIN SVK PATCH BLOCK ====
Version: svk 1.05 (linux)

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
Hwr+RFg=
==== END SVK PATCH BLOCK ====


More information about the Rt-devel mailing list