[Rt-commit] r1992 - in rt/branches/3.3-TESTING: . lib/RT
jesse at bestpractical.com
jesse at bestpractical.com
Thu Dec 16 14:47:58 EST 2004
Author: jesse
Date: Tue Dec 14 02:25:03 2004
New Revision: 1992
Modified:
rt/branches/3.3-TESTING/ (props changed)
rt/branches/3.3-TESTING/lib/RT/Tickets_Overlay.pm
rt/branches/3.3-TESTING/lib/RT/Tickets_Overlay_SQL.pm
Log:
r2428 at hualien: jesse | 2004-12-14T07:21:15.616305Z
Adding support for searching on tickets which have no relationships of a given type (Such as "HasMember IS NULL") for clkao
Modified: rt/branches/3.3-TESTING/lib/RT/Tickets_Overlay.pm
==============================================================================
--- rt/branches/3.3-TESTING/lib/RT/Tickets_Overlay.pm (original)
+++ rt/branches/3.3-TESTING/lib/RT/Tickets_Overlay.pm Tue Dec 14 02:25:03 2004
@@ -308,64 +308,118 @@
=cut
sub _LinkLimit {
- my ($sb,$field,$op,$value, at rest) = @_;
-
- die "Op must be ="
- unless $op eq "=";
+ my ( $sb, $field, $op, $value, @rest ) = @_;
- my $meta = $FIELDS{$field};
- die "Incorrect Meta Data for $field"
- unless (defined $meta->[1] and defined $meta->[2]);
+ my $meta = $FIELDS{$field};
+ die "Invalid Operator $op for $field" unless $op =~ /^(=|!=|IS)/io;
- $sb->{_sql_linkalias} = $sb->NewAlias ('Links')
- unless defined $sb->{_sql_linkalias};
+ die "Incorrect Metadata for $field"
+ unless ( defined $meta->[1] and defined $meta->[2] );
- $sb->_OpenParen();
+ my $direction = $meta->[1];
- $sb->_SQLLimit(
- ALIAS => $sb->{_sql_linkalias},
- FIELD => 'Type',
- OPERATOR => '=',
- VALUE => $meta->[2],
- @rest,
- );
+ my $matchfield;
+ my $linkfield;
+ my $is_local = 1;
+ my $is_null = 0;
+ if ( $direction eq 'To' ) {
+ $matchfield = "Target";
+ $linkfield = "Base";
- if ($meta->[1] eq "To") {
- my $matchfield = ( $value =~ /^(\d+)$/ ? "LocalTarget" : "Target" );
+ }
+ elsif ( $direction eq 'From' ) {
+ $linkfield = "Target";
+ $matchfield = "Base";
- $sb->_SQLLimit(
- ALIAS => $sb->{_sql_linkalias},
- ENTRYAGGREGATOR => 'AND',
- FIELD => $matchfield,
- OPERATOR => '=',
- VALUE => $value ,
- );
+ }
+ else {
+ die "Invalid link direction '$meta->[1]' for $field\n";
+ }
- #If we're searching on target, join the base to ticket.id
- $sb->_SQLJoin( ALIAS1 => 'main', FIELD1 => $sb->{'primary_key'},
- ALIAS2 => $sb->{_sql_linkalias}, FIELD2 => 'LocalBase');
+ if ( $op eq '=' || $op =~ /^is/oi ) {
+ if ( $value eq '' || $value =~ /^null$/io ) {
+ $is_null = 1;
+ # When doing null searches, we need to turn everything around. WHY?
+ my $tmp = $linkfield;
+ $linkfield = $matchfield;
+ $matchfield = $tmp;
+ }
+ elsif ( $value =~ /\D/o ) {
+ $is_local = 0;
+ }
+ else {
+ $is_local = 1;
+ }
+ }
- } elsif ( $meta->[1] eq "From" ) {
- my $matchfield = ( $value =~ /^(\d+)$/ ? "LocalBase" : "Base" );
+#For doing a left join to find "unlinked tickets" we want to generate a query that looks like this
+# SELECT main.* FROM Tickets main
+# LEFT JOIN Links Links_1 ON ( (Links_1.Type = 'MemberOf')
+# AND(main.id = Links_1.LocalTarget))
+# WHERE ((main.EffectiveId = main.id))
+# AND ((main.Status != 'deleted'))
+# AND (Links_1.LocalBase IS NULL);
+
+ if ($is_null) {
+ my $linkalias = $sb->Join(
+ TYPE => 'left',
+ ALIAS1 => 'main',
+ FIELD1 => 'id',
+ TABLE2 => 'Links',
+ FIELD2 => 'Local' . $linkfield
+ );
+
+ $sb->SUPER::Limit(
+ LEFTJOIN => $linkalias,
+ FIELD => 'Type',
+ OPERATOR => '=',
+ VALUE => $meta->[2],
+ @rest,
+ );
+
+ $sb->_SQLLimit(
+ ALIAS => $linkalias,
+ ENTRYAGGREGATOR => 'AND',
+ FIELD => ( $is_local ? "Local$matchfield" : $matchfield ),
+ OPERATOR => 'IS',
+ VALUE => 'NULL',
+ QUOTEVALUE => '0',
+ );
- $sb->_SQLLimit(
- ALIAS => $sb->{_sql_linkalias},
- ENTRYAGGREGATOR => 'AND',
- FIELD => $matchfield,
- OPERATOR => '=',
- VALUE => $value ,
- );
+ }
+ else {
- #If we're searching on base, join the target to ticket.id
- $sb->_SQLJoin( ALIAS1 => 'main', FIELD1 => $sb->{'primary_key'},
- ALIAS2 => $sb->{_sql_linkalias}, FIELD2 => 'LocalTarget');
+ $sb->{_sql_linkalias} = $sb->NewAlias('Links')
+ unless defined $sb->{_sql_linkalias};
- } else {
- die "Invalid link direction '$meta->[1]' for $field\n";
- }
+ $sb->_OpenParen();
- $sb->_CloseParen();
+ $sb->_SQLLimit(
+ ALIAS => $sb->{_sql_linkalias},
+ FIELD => 'Type',
+ OPERATOR => '=',
+ VALUE => $meta->[2],
+ @rest,
+ );
+
+ $sb->_SQLLimit(
+ ALIAS => $sb->{_sql_linkalias},
+ ENTRYAGGREGATOR => 'AND',
+ FIELD => ( $is_local ? "Local$matchfield" : $matchfield ),
+ OPERATOR => '=',
+ VALUE => $value,
+ );
+
+ #If we're searching on target, join the base to ticket.id
+ $sb->_SQLJoin(
+ ALIAS1 => 'main',
+ FIELD1 => $sb->{'primary_key'},
+ ALIAS2 => $sb->{_sql_linkalias},
+ FIELD2 => 'Local' . $linkfield
+ );
+ $sb->_CloseParen();
+ }
}
=head2 _DateLimit
Modified: rt/branches/3.3-TESTING/lib/RT/Tickets_Overlay_SQL.pm
==============================================================================
--- rt/branches/3.3-TESTING/lib/RT/Tickets_Overlay_SQL.pm (original)
+++ rt/branches/3.3-TESTING/lib/RT/Tickets_Overlay_SQL.pm Tue Dec 14 02:25:03 2004
@@ -157,7 +157,7 @@
my $re_aggreg = qr[(?i:AND|OR)];
my $re_delim = qr[$RE{delimited}{-delim=>qq{\'\"}}];
-my $re_value = qr[$re_delim|\d+];
+my $re_value = qr[$re_delim|\d+|NULL];
my $re_keyword = qr[$re_delim|(?:\{|\}|\w|\.)+];
my $re_op = qr[=|!=|>=|<=|>|<|(?i:IS NOT)|(?i:IS)|(?i:NOT LIKE)|(?i:LIKE)]; # long to short
my $re_open_paren = qr'\(';
More information about the Rt-commit
mailing list