[Rt-devel] PATCH 3.6 - Make search config fields mutable

Todd Chapman todd at chaka.net
Mon Jul 31 22:21:04 EDT 2006


The attached patch makes it easier to extend TicektSQL.
Passes regression tests. Additional regression tests
included.

-Todd
-------------- next part --------------
==== Patch <tickets> level 1
Source: 6fc35107-3207-0410-b21e-9a2d7f624572:/local/bp/rt/features/3.6_mutable_search_fields:8059
Target: e417ac7c-1bcc-0310-8ffa-8f5827389a85:/rt/branches/3.6-RELEASE:5658
        (svn://svn.bestpractical.com)
Log:
 r8058 at slah001:  root | 2006-07-31 21:56:10 -0400
 Make it easier to extend searching.
 r8059 at slah001:  root | 2006-07-31 22:07:33 -0400
 Make search configuration fields mutable.

=== lib/t/regression/12-search.t
==================================================================
--- lib/t/regression/12-search.t	(revision 5658)
+++ lib/t/regression/12-search.t	(patch tickets level 1)
@@ -6,7 +6,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 44;
+use Test::More tests => 87;
 use_ok('RT');
 RT::LoadConfig();
 RT::Init();
@@ -264,3 +264,83 @@
 $tix->FromSQL("CF.SearchTest = 'foo1' OR CF.SearchTest = 'foo3' OR CF.SearchTest2 = 'bar1' OR CF.SearchTest2 = 'bar2'");
 is($tix->Count, 3, "is cf1 or is cf1 or is cf2 or is cf2");
 
+# test class methods
+{
+# _mutable_hash
+my $hashref = { This => 1, That => 2 };
+is( RT::Tickets->_mutable_hash( $hashref ), $hashref, "returns hashref");
+is( RT::Tickets->_mutable_hash( $hashref, 'Unknown' ), undef, "unknown field returns undef");
+is( RT::Tickets->_mutable_hash( $hashref, 1 ), undef, "returns undef");
+is( RT::Tickets->_mutable_hash( $hashref, [] ), undef, "returns undef");
+is( RT::Tickets->_mutable_hash( $hashref, 'This' ), 1, "returns value");
+my $old_value =  RT::Tickets->_mutable_hash( $hashref, 'This', 3 );
+is( $old_value, 1, "got old value");
+is( RT::Tickets->_mutable_hash( $hashref, 'This' ), 3, "got new value");
+$old_value =  RT::Tickets->_mutable_hash( $hashref, 'This', undef );
+is( $old_value, 3, "got old value");
+is( RT::Tickets->_mutable_hash( $hashref, 'This' ), undef, "got new value");
+}
+
+{
+# FIELDS()
+is(ref(RT::Tickets->FIELDS()),              'HASH', "FIELDS() returns hashref");
+is(RT::Tickets->FIELDS('random_junk_xzy'),   undef, "Unknown field name returns undef");
+is(ref(RT::Tickets->FIELDS('id')),         'ARRAY', "Known field name returns hashref");
+is(RT::Tickets->FIELDS('id')->[0],           'INT', "Known field name returns hashref");
+my $old_value = RT::Tickets->FIELDS('Owner');
+is($old_value->[0],                     'WATCHERFIELD', "Known field name returns hashref");
+is($old_value->[1],                            'Owner', "Known field name returns hashref");
+my $new_value = [ 'ENUM' => 'User' ];
+my $value = RT::Tickets->FIELDS('Owner', $new_value);
+is($value->[0],                         'WATCHERFIELD', "Old value is returned");
+is($value->[1],                                'Owner', "Old value is returned");
+$value = RT::Tickets->FIELDS('Owner');
+is($value->[0],                             'ENUM', "New value is set");
+is($value->[1],                             'User', "New value is set");
+$value = RT::Tickets->FIELDS('Owner', undef);
+is($value->[0],                         'ENUM', "Old value is returned");
+is($value->[1],                                'User', "Old value is returned");
+$value = RT::Tickets->FIELDS('Owner');
+is($value,                                   undef, "Value is deleted");
+$value = RT::Tickets->FIELDS('Owner', $old_value);
+is($value->[0],                                undef, "Old value is returned");
+$value = RT::Tickets->FIELDS('Owner');
+is($value->[0],                     'WATCHERFIELD', "Old value is restored");
+is($value->[1],                            'Owner', "Old value is restored");
+RT::Tickets->FIELDS('Owner', { 'This should' => 'not work' });
+$value = RT::Tickets->FIELDS('Owner');
+is($value->[0],                     'WATCHERFIELD', "Old value is restored");
+is($value->[1],                            'Owner', "Old value is restored");
+}
+
+{
+# dispatch
+is(ref(RT::Tickets->dispatch()),              'HASH', "dispatch() returns hashref");
+is(RT::Tickets->dispatch('random_junk_xzy'),   undef, "Unknown field type returns undef");
+is(ref(RT::Tickets->dispatch('INT')),         'CODE', "Known field type returns coderef");
+my $old_value = RT::Tickets->dispatch('INT');
+is($old_value,              \&RT::Tickets::_IntLimit, "Known field type returns coderef");
+my $new_value = \&RT::Tickets::_StringLimit;
+my $value = RT::Tickets->dispatch('INT', $new_value);
+is($value,                   \&RT::Tickets::_IntLimit, "Old value is returned");
+$value = RT::Tickets->dispatch('INT');
+is($value,                    \&RT::Tickets::_StringLimit, "New value is set");
+$value = RT::Tickets->dispatch('INT', undef);
+is($value,                    \&RT::Tickets::_StringLimit, "Old value is returned");
+$value = RT::Tickets->dispatch('INT');
+is($value,                                   undef, "Value is deleted");
+$value = RT::Tickets->dispatch('INT', $old_value);
+is($value,                                undef, "Old value is returned");
+$value = RT::Tickets->dispatch('INT');
+is($value,                     \&RT::Tickets::_IntLimit, "Old value is restored");
+RT::Tickets->dispatch('INT', { 'This should' => 'not work' });
+$value = RT::Tickets->dispatch('INT');
+is($value,                     \&RT::Tickets::_IntLimit, "Old value is restored");
+}
+
+is(ref(RT::Tickets->DefaultEA()),            'HASH', "DefaultEA() returns hashref");
+is(    RT::Tickets->DefaultEA('INT'),         'AND', "DefaultEA() returns string");
+is(ref(RT::Tickets->DefaultEA('DATE')),      'HASH', "DefaultEA() returns hashref");
+
+is(ref(RT::Tickets->can_bundle()),              'HASH', "can_bundle() returns hashref");
+is(    RT::Tickets->can_bundle('WATCHERFIELD'), 'yes', "can_bundle() returns string");
=== lib/RT/Tickets_Overlay.pm
==================================================================
--- lib/RT/Tickets_Overlay.pm	(revision 5658)
+++ lib/RT/Tickets_Overlay.pm	(patch tickets level 1)
@@ -202,10 +202,121 @@
 
 # Helper functions for passing the above lexically scoped tables above
 # into Tickets_Overlay_SQL.
-sub FIELDS     { return \%FIELD_METADATA }
-sub dispatch   { return \%dispatch }
-sub can_bundle { return \%can_bundle }
 
+=head2 FIELDS
+
+With no arguments returns a hash reference which is a mapping of
+searchable Field name, to Type, and other metadata.
+The keys are field names and the values are references to arrays:
+
+RT::Tickets->FIELDS()
+
+With one argument returns the array reference for that field name,
+or undef if it is not found:
+
+RT::Tickets->FIELDS('MyField')
+
+With two arguments sets the field name given in the first argument
+the value in the second argument. The second argument must either
+be an array reference, or undef, in which case the field is deleted
+from the map table:
+
+RT::Tickets->FIELDS('MyField', [ 'INT', ] )
+RT::Tickets->FIELDS('MyField', undef )
+
+For backward compatability FIELDS can be called as a function with
+no arguments, but must be called as a method if passing arguments.
+
+=cut
+
+sub FIELDS {
+
+    my $self = shift;
+
+    if ( @_ == 2 and $_[1] ) {
+        unless ( ref($_[1]) eq 'ARRAY' ) {
+            $RT::Logger->error("Second argument to FIELDS must be an array reference or undef!");
+            pop;
+        }
+    }
+
+    return __PACKAGE__->_mutable_hash(\%FIELD_METADATA, @_);
+}
+
+=head2 dispatch
+
+With no arguments returns a hash reference which is a mapping of
+searchable Field type, to limit function.
+The keys are field types and the values are code references:
+
+RT::Tickets->dispatch()
+
+With one argument returns the code reference for that field type,
+or undef if it is not found:
+
+RT::Tickets->dispatch(INT)
+
+With two arguments sets the field type given in the first argument
+the value in the second argument. The second argument must either
+be an code reference, or undef, in which case the field is deleted
+from the map table:
+
+RT::Tickets->dispatch(INT => \&_IntLimit)
+RT::Tickets->dispatch(INT => undef )
+
+=cut
+
+sub dispatch {
+
+    my $self = shift;
+
+    if ( @_ == 2 and $_[1] ) {
+        unless ( ref($_[1]) eq 'CODE' ) {
+            $RT::Logger->error("Second argument to dispatch must be a code reference or undef!");
+            pop;
+        }
+    }
+
+    return __PACKAGE__->_mutable_hash(\%dispatch, @_);
+}
+
+sub can_bundle {
+
+    my $self = shift;
+    return __PACKAGE__->_mutable_hash(\%can_bundle, @_);
+
+}
+
+=head2 DefaultEA
+
+With no arguments returns a hash reference which is a mapping of
+searchable Field type, to its default Entry aggregator.
+The keys are field types and the values strings or hash references:
+
+RT::Tickets->DefaultEA()
+
+With one argument returns the string or hash reference for that
+field type, or undef if it is not found:
+
+RT::Tickets->DefaultEA(INT)
+
+With two arguments sets the field type given in the first argument
+the value in the second argument. The second argument must either
+be a string, hash reference, or undef, in which case the field is
+deleted from the map table:
+
+RT::Tickets->DefaultEA(LINK => 'OR')
+RT::Tickets->DefaultEA(LINK => undef )
+
+=cut
+
+sub DefaultEA {
+
+    my $self = shift;
+    return __PACKAGE__->_mutable_hash(\%DefaultEA, @_);
+
+}
+
 # Bring in the clowns.
 require RT::Tickets_Overlay_SQL;
 
@@ -2889,6 +3000,33 @@
     $self->RedoSearch();
 }
 
+sub _mutable_hash {
+
+    my $self  = shift;
+    my $hashref = shift;
+
+    unless ( ref($hashref) eq 'HASH' ) {
+        $RT::Logger->error("The first argument to _mutable must be a hash reference!");
+        return undef;
+    }
+
+    if ( @_ == 1  ) {
+        return $hashref->{ $_[0] };
+    }
+    elsif ( @_ == 2  ) {
+        my $old_value = $hashref->{ $_[0] };
+        if ( $_[1] ) {
+            $hashref->{ $_[0] } = $_[1];
+        }
+        else {
+            delete $hashref->{ $_[0] };
+        }
+        return $old_value;
+    }
+
+    return $hashref;
+}
+
 =head1 FLAGS
 
 RT::Tickets supports several flags which alter search behavior:

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

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
h3p4iA==
==== END SVK PATCH BLOCK ====


More information about the Rt-devel mailing list