[Rt-commit] rt branch, 4.0/columnmap-cache-cf, created. rt-4.0.6-169-g47fc745
Alex Vandiver
alexmv at bestpractical.com
Tue Jun 12 17:15:52 EDT 2012
The branch, 4.0/columnmap-cache-cf has been created
at 47fc745e4f578d3e4ad2eb914af8dd9472d4fbb9 (commit)
- Log -----------------------------------------------------------------
commit dda0fa00bb70334a770d2cc35f012bad2ff61eba
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Tue Jun 12 13:57:27 2012 -0400
RT::ObjectCustomFieldValues calls LimitToEnabled by default
This cleans up an unnecessary (Disabled = 0 OR Disabled = 0)
diff --git a/lib/RT/CustomField.pm b/lib/RT/CustomField.pm
index 2002d4e..d065b7f 100644
--- a/lib/RT/CustomField.pm
+++ b/lib/RT/CustomField.pm
@@ -1656,7 +1656,6 @@ sub ValuesForObject {
$values->LimitToCustomField($self->Id);
- $values->LimitToEnabled();
$values->LimitToObject($object);
return ($values);
commit ce698ecd6bb2c5198442e2ca65cbbb84ad12e764
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Tue Jun 12 16:30:27 2012 -0400
Move "global or queue" logic to LoadCustomFieldByIdentifier
The logic for attempting to load a queue-specific queue, and then the
global one, was on the CustomFieldValues method. Move the logic to
LoadCustomFieldByIdentifier, which is called by
RT::Record->CustomFieldValues, rather than overriding CustomFieldValues
directly; this allows other methods to simple call
->LoadCustomFieldByIdentifier and gain the queue-or-global
functionality.
This change also causes ->CustomFieldValues (and thus both
->FirstCustomFieldValue and ->CustomFieldValuesAsString), when called on
tickets with an invalid CF name, to warn. This makes it consistent with
->CustomFieldValues called on other types of objects, and may provide
useful feedback when a CF name is improperly specified.
diff --git a/lib/RT/Ticket.pm b/lib/RT/Ticket.pm
index c6a5e5b..e4c5384 100644
--- a/lib/RT/Ticket.pm
+++ b/lib/RT/Ticket.pm
@@ -3666,37 +3666,29 @@ sub TransactionCustomFields {
}
+=head2 LoadCustomFieldByIdentifier
-=head2 CustomFieldValues
-
-# Do name => id mapping (if needed) before falling back to
-# RT::Record's CustomFieldValues
-
-See L<RT::Record>
+Finds and returns the custom field of the given name for the ticket,
+overriding L<RT::Record/LoadCustomFieldByIdentifier> to look for
+queue-specific CFs before global ones.
=cut
-sub CustomFieldValues {
+sub LoadCustomFieldByIdentifier {
my $self = shift;
my $field = shift;
- return $self->SUPER::CustomFieldValues( $field ) if !$field || $field =~ /^\d+$/;
+ return $self->SUPER::LoadCustomFieldByIdentifier($field)
+ if ref $field or $field =~ /^\d+$/;
my $cf = RT::CustomField->new( $self->CurrentUser );
$cf->SetContextObject( $self );
$cf->LoadByNameAndQueue( Name => $field, Queue => $self->Queue );
- unless ( $cf->id ) {
- $cf->LoadByNameAndQueue( Name => $field, Queue => 0 );
- }
-
- # If we didn't find a valid cfid, give up.
- return RT::ObjectCustomFieldValues->new( $self->CurrentUser ) unless $cf->id;
-
- return $self->SUPER::CustomFieldValues( $cf->id );
+ $cf->LoadByNameAndQueue( Name => $field, Queue => 0 ) unless $cf->id;
+ return $cf;
}
-
=head2 CustomFieldLookupType
Returns the RT::Ticket lookup type, which can be passed to
diff --git a/lib/RT/Transaction.pm b/lib/RT/Transaction.pm
index 5b3641f..fa2c56f 100644
--- a/lib/RT/Transaction.pm
+++ b/lib/RT/Transaction.pm
@@ -1175,37 +1175,31 @@ sub UpdateCustomFields {
}
}
+=head2 LoadCustomFieldByIdentifier
-
-=head2 CustomFieldValues
-
- Do name => id mapping (if needed) before falling back to RT::Record's CustomFieldValues
-
- See L<RT::Record>
+Finds and returns the custom field of the given name for the
+transaction, overriding L<RT::Record/LoadCustomFieldByIdentifier> to
+look for queue-specific CFs before global ones.
=cut
-sub CustomFieldValues {
+sub LoadCustomFieldByIdentifier {
my $self = shift;
my $field = shift;
- if ( UNIVERSAL::can( $self->Object, 'QueueObj' ) ) {
-
- # XXX: $field could be undef when we want fetch values for all CFs
- # do we want to cover this situation somehow here?
- unless ( defined $field && $field =~ /^\d+$/o ) {
- my $CFs = RT::CustomFields->new( $self->CurrentUser );
- $CFs->SetContextObject( $self->Object );
- $CFs->Limit( FIELD => 'Name', VALUE => $field );
- $CFs->LimitToLookupType($self->CustomFieldLookupType);
- $CFs->LimitToGlobalOrObjectId($self->Object->QueueObj->id);
- $field = $CFs->First->id if $CFs->First;
- }
- }
- return $self->SUPER::CustomFieldValues($field);
-}
+ return $self->SUPER::LoadCustomFieldByIdentifier($field)
+ if ref $field or $field =~ /^\d+$/;
+ return $self->SUPER::LoadCustomFieldByIdentifier($field)
+ unless UNIVERSAL::can( $self->Object, 'QueueObj' );
+ my $CFs = RT::CustomFields->new( $self->CurrentUser );
+ $CFs->SetContextObject( $self->Object );
+ $CFs->Limit( FIELD => 'Name', VALUE => $field );
+ $CFs->LimitToLookupType($self->CustomFieldLookupType);
+ $CFs->LimitToGlobalOrObjectId($self->Object->QueueObj->id);
+ return $CFs->First || RT::CustomField->new( $self->CurrentUser );
+}
=head2 CustomFieldLookupType
diff --git a/t/customfields/api.t b/t/customfields/api.t
index d739a57..228693f 100644
--- a/t/customfields/api.t
+++ b/t/customfields/api.t
@@ -3,7 +3,8 @@
use strict;
use warnings FATAL => 'all';
-use RT::Test nodata => 1, tests => 139;
+use RT::Test nodata => 1, tests => 145;
+use Test::Warn;
# Before we get going, ditch all object_cfs; this will remove
# all custom fields systemwide;
@@ -69,13 +70,21 @@ is( $cfvs->Count, 0 );
is( $ticket->FirstCustomFieldValue, undef );
# CF with ID -1 shouldnt exist at all
-$cfvs = $ticket->CustomFieldValues( -1 );
+warning_like {
+ $cfvs = $ticket->CustomFieldValues( -1 );
+} qr{Couldn't load custom field};
is( $cfvs->Count, 0 );
-is( $ticket->FirstCustomFieldValue( -1 ), undef );
+warning_like {
+ is( $ticket->FirstCustomFieldValue( -1 ), undef );
+} qr{Couldn't load custom field};
-$cfvs = $ticket->CustomFieldValues( 'SomeUnexpedCustomFieldName' );
+warning_like {
+ $cfvs = $ticket->CustomFieldValues( 'SomeUnexpedCustomFieldName' );
+} qr{Couldn't load custom field};
is( $cfvs->Count, 0 );
-is( $ticket->FirstCustomFieldValue( 'SomeUnexpedCustomFieldName' ), undef );
+warning_like {
+ is( $ticket->FirstCustomFieldValue( 'SomeUnexpedCustomFieldName' ), undef );
+} qr{Couldn't load custom field};
for (@custom_fields) {
$cfvs = $ticket->CustomFieldValues( $_->id );
@@ -183,9 +192,13 @@ $test_add_delete_cycle->( sub { return $_[0] } );
$ticket->AddCustomFieldValue( Field => $local_cf2->id , Value => 'Baz' );
$ticket->AddCustomFieldValue( Field => $global_cf3->id , Value => 'Baz' );
# now if we ask for cf values on RecordCustomFields4 we should not get any
-$cfvs = $ticket->CustomFieldValues( 'RecordCustomFields4' );
+warning_like {
+ $cfvs = $ticket->CustomFieldValues( 'RecordCustomFields4' );
+} qr{Couldn't load custom field};
is( $cfvs->Count, 0, "No custom field values for non-Queue cf" );
-is( $ticket->FirstCustomFieldValue( 'RecordCustomFields4' ), undef, "No first custom field value for non-Queue cf" );
+warning_like {
+ is( $ticket->FirstCustomFieldValue( 'RecordCustomFields4' ), undef, "No first custom field value for non-Queue cf" );
+} qr{Couldn't load custom field};
{
my $cfname = $global_cf3->Name;
commit 47fc745e4f578d3e4ad2eb914af8dd9472d4fbb9
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Tue Jun 12 16:41:38 2012 -0400
Cache CFs in ColumnMap on a per-request basis
When displaying /n/ rows of search results with /m/ columns of global CF
values displayed, custom field queries accounted for /n/ * /m/ * 3
queries; one to try to load the queue-specific CF with the column name,
one to load the global CF with that name, and one to load the OCFV for
that CF and ticket. With sufficient CFs in a search result format,
these account for a significant performance impact, despite beign
relatively well-indexed.
Cache the CF objects in the per-request $m->notes() cache to eliminate
the CF loads, which account for ½ to â
of those queries, depending on
the prevalence of global CFs. The cache key must also include the queue
name, as a single search may include results from multiple queues, each
of which may resolve a CF name differently.
diff --git a/share/html/Elements/ColumnMap b/share/html/Elements/ColumnMap
index 87fd61b..889053b 100644
--- a/share/html/Elements/ColumnMap
+++ b/share/html/Elements/ColumnMap
@@ -96,13 +96,25 @@ my $COLUMN_MAP = {
attribute => sub { return shift @_ },
title => sub { return pop @_ },
value => sub {
+ # Cache the CF object on a per-request basis, to avoid
+ # having to load it for every row
+ my $key = "CF--$_[-1]";
+ $key = "CF-".$_[0]->Queue."-$_[-1]" if $_[0]->isa("RT::Ticket");
+ $key = "CF-".$_[0]->Object->Queue."-$_[-1]" if $_[0]->isa("RT::Transaction")
+ and $_[0]->Object->isa("RT::Ticket");
+
+ my $cf = $m->notes($key);
+ unless ($cf) {
+ $cf = $_[0]->LoadCustomFieldByIdentifier($_[-1]);
+ $m->notes($key, $cf);
+ }
+
# Display custom field contents, separated by newlines.
# For Image custom fields we also show a thumbnail here.
-
- my $values = $_[0]->CustomFieldValues( $_[-1] );
+ my $values = $cf->ValuesForObject( $_[0] );
my @values = map {
(
- ($_->CustomFieldObj->Type eq 'Image')
+ ($cf->Type eq 'Image')
? \($m->scomp( '/Elements/ShowCustomFieldImage', Object => $_ ))
: $_->Content
),
-----------------------------------------------------------------------
More information about the Rt-commit
mailing list