diff options
author | sunnavy <sunnavy@bestpractical.com> | 2022-10-20 23:51:56 +0300 |
---|---|---|
committer | sunnavy <sunnavy@bestpractical.com> | 2022-10-28 00:08:55 +0300 |
commit | f82adc3bf13fbd509937353f9c712c7aee77eeb0 (patch) | |
tree | 787169300ee9e1e4f13363e1bc8350adef46beb4 | |
parent | b440822a33f6ba6448837c55821c3fac3b590227 (diff) |
Tweak UID generation code and also cache user UID for performance
-rw-r--r-- | lib/RT/Attribute.pm | 17 | ||||
-rw-r--r-- | lib/RT/Group.pm | 30 | ||||
-rw-r--r-- | lib/RT/Record.pm | 49 | ||||
-rw-r--r-- | lib/RT/Ticket.pm | 4 | ||||
-rw-r--r-- | lib/RT/Transaction.pm | 31 | ||||
-rw-r--r-- | lib/RT/User.pm | 3 |
6 files changed, 87 insertions, 47 deletions
diff --git a/lib/RT/Attribute.pm b/lib/RT/Attribute.pm index d8d2db1434..4e0201b542 100644 --- a/lib/RT/Attribute.pm +++ b/lib/RT/Attribute.pm @@ -995,18 +995,13 @@ sub Serialize { my $content = $self->_DeserializeContent($store{Content}); for my $pane (values %{ $content || {} }) { for (@$pane) { - my $attr = RT::Attribute->new($self->CurrentUser); - $attr->LoadById($_); - $_ = \($attr->UID); + $_ = \( join '-', 'RT::Attribute', $RT::Organization, $_ ); } } $store{Content} = $self->_SerializeContent($content); } elsif ( $store{Name} =~ /DefaultDashboard$/ ) { - my $content = $store{Content}; - my $attr = RT::Attribute->new( $self->CurrentUser ); - $attr->LoadById($content); - $store{Content} = \$attr->UID; + $store{Content} = \( join '-', 'RT::Attribute', $RT::Organization, $store{Content} ); } # encode saved searches and dashboards to be UIDs elsif ($store{Name} eq 'Dashboard') { @@ -1014,9 +1009,7 @@ sub Serialize { for my $pane (values %{ $content->{Panes} || {} }) { for (@$pane) { if ($_->{portlet_type} eq 'search' || $_->{portlet_type} eq 'dashboard') { - my $attr = RT::Attribute->new($self->CurrentUser); - $attr->LoadById($_->{id}); - $_->{uid} = \($attr->UID); + $_->{uid} = \( join '-', 'RT::Attribute', $RT::Organization, $_->{id} ); } # pass through everything else (e.g. component) } @@ -1026,9 +1019,7 @@ sub Serialize { # encode subscriptions to have dashboard UID elsif ($store{Name} eq 'Subscription') { my $content = $self->_DeserializeContent($store{Content}); - my $attr = RT::Attribute->new($self->CurrentUser); - $attr->LoadById($content->{DashboardId}); - $content->{DashboardId} = \($attr->UID); + $content->{DashboardId} = \( join '-', 'RT::Attribute', $RT::Organization, $content->{DashboardId} ); $store{Content} = $self->_SerializeContent($content); } diff --git a/lib/RT/Group.pm b/lib/RT/Group.pm index 308f05955e..f466235830 100644 --- a/lib/RT/Group.pm +++ b/lib/RT/Group.pm @@ -1355,6 +1355,15 @@ sub PrincipalId { sub InstanceObj { my $self = shift; + my $class = $self->InstanceClass or return; + + my $obj = $class->new( $self->CurrentUser ); + $obj->Load( $self->Instance ); + return $obj; +} + +sub InstanceClass { + my $self = shift; my $class; if ( $self->Domain eq 'ACLEquivalence' ) { $class = "RT::User"; @@ -1365,12 +1374,7 @@ sub InstanceObj { } elsif ($self->Domain eq 'RT::Asset-Role') { $class = "RT::Asset"; } - - return unless $class; - - my $obj = $class->new( $self->CurrentUser ); - $obj->Load( $self->Instance ); - return $obj; + return $class; } sub BasicColumns { @@ -1670,8 +1674,18 @@ sub Serialize { my %args = (@_); my %store = $self->SUPER::Serialize(@_); - my $instance = $self->InstanceObj; - $store{Instance} = \($instance->UID) if $instance; + if ( my $class = $self->InstanceClass ) { + if ( $class->can('UID') eq RT::Record->can('UID') ) { + $store{Instance} = \( join '-', $class, $RT::Organization, $store{Instance} ); + } + elsif ( $class eq 'RT::User' ) { + $store{Instance} = \$args{serializer}{_uid}{user}{ $store{Instance} }; + } + else { + my $instance = $self->InstanceObj; + $store{Instance} = \($instance->UID); + } + } $store{Disabled} = $self->PrincipalObj->Disabled; $store{Principal} = $self->PrincipalObj->UID; diff --git a/lib/RT/Record.pm b/lib/RT/Record.pm index 13691bf1ad..fc2bfa48eb 100644 --- a/lib/RT/Record.pm +++ b/lib/RT/Record.pm @@ -69,6 +69,7 @@ use warnings; use RT; use base RT->Config->Get('RecordBaseClass'); use base 'RT::Base'; +use v5.10; require RT::Date; require RT::User; @@ -2837,8 +2838,19 @@ sub Serialize { } return %store unless $args{UIDs}; + state %simple_uid_class; + # Use FooObj to turn Foo into a reference to the UID for my $col ( grep {$store{$_}} @cols ) { + next if $col =~ /^(?:Created|LastUpdated)$/;; + + if ( $self->isa('RT::Ticket') ) { + next if $col =~ /^(?:Due|Resolved|Starts|Started|Told)$/; + } + elsif ( $self->isa('RT::Group') ) { + next if $col eq 'Instance'; + } + my $method = $methods{$col}; if (not $method) { $method = $col; @@ -2846,15 +2858,44 @@ sub Serialize { } next unless $self->can($method); - my $obj = $self->$method; - next unless $obj and $obj->isa("RT::Record"); - $store{$col} = \($obj->UID); + my $uid; + + my $value = $self->$col; + if ( $simple_uid_class{ ref $self }{$col} && $value =~ /^\d+$/ && $value > 0 ) { + + # UID is based on id, so we can generate UID directly + $uid = join '-', $simple_uid_class{ ref $self }{$col}, $RT::Organization, $value; + } + elsif ( $method =~ /^(?:Creator|LastUpdatedBy)Obj$/ || ( $self->isa('RT::Ticket') && $method eq 'OwnerObj' ) ) { + $uid = $args{serializer}{_uid}{user}{$value} if $value; + } + + if (!$uid) { + my $obj = $self->$method; + next unless $obj and $obj->isa("RT::Record"); + $uid = $obj->UID; + + if ( $obj->can('UID') eq RT::Record->can('UID') ) { + # Group Instance column points to various classes. + $simple_uid_class{ ref $self }{$col} = ref $obj; + } + } + + $store{$col} = \$uid if $uid; } # Anything on an object should get the UID stored instead if ($store{ObjectType} and $store{ObjectId} and $self->can("Object")) { + if ( $store{ObjectType}->can('UID') eq RT::Record->can('UID') ) { + $store{Object} = \( join '-', $store{ObjectType}, $RT::Organization, $store{ObjectId} ); + } + elsif ( $store{ObjectType} eq 'RT::User' ) { + $store{Object} = \( $args{serializer}{uid}{user}{ $store{ObjectId} } ||= $self->Object->UID ); + } + else { + $store{Object} = \( $self->Object->UID ); + } delete $store{$_} for qw/ObjectType ObjectId/; - $store{Object} = \($self->Object->UID); } return %store; diff --git a/lib/RT/Ticket.pm b/lib/RT/Ticket.pm index d63881f79e..4d858a8b8f 100644 --- a/lib/RT/Ticket.pm +++ b/lib/RT/Ticket.pm @@ -3759,9 +3759,7 @@ sub Serialize { my %args = (@_); my %store = $self->SUPER::Serialize(@_); - my $obj = RT::Ticket->new( RT->SystemUser ); - $obj->Load( $store{EffectiveId} ); - $store{EffectiveId} = \($obj->UID); + $store{EffectiveId} = \( join '-', 'RT::Ticket', $RT::Organization, $store{EffectiveId} ); return %store; } diff --git a/lib/RT/Transaction.pm b/lib/RT/Transaction.pm index 4f1286bf1b..b7c5e89405 100644 --- a/lib/RT/Transaction.pm +++ b/lib/RT/Transaction.pm @@ -2158,26 +2158,21 @@ sub Serialize { my $type = $store{Type}; if ($type eq "CustomField") { - my $cf = RT::CustomField->new( RT->SystemUser ); - $cf->Load( $store{Field} ); - $store{Field} = \($cf->UID); - - $store{OldReference} = \($self->OldReferenceObject->UID) if $self->OldReference; - $store{NewReference} = \($self->NewReferenceObject->UID) if $self->NewReference; - } elsif ($type =~ /^(Take|Untake|Force|Steal|Give)$/) { + $store{Field} = \( join '-', 'RT::CustomField', $RT::Organization, $store{Field} ); + + $store{OldReference} = \( join '-', $store{ReferenceType}, $RT::Organization, $store{OldReference} ) + if $store{OldReference}; + $store{NewReference} = \( join '-', $store{ReferenceType}, $RT::Organization, $store{NewReference} ) + if $store{NewReference}; + } + elsif ($type =~ /^(Take|Untake|Force|Steal|Give)$/) { for my $field (qw/OldValue NewValue/) { - my $user = RT::User->new( RT->SystemUser ); - $user->Load( $store{$field} ); - $store{$field} = \($user->UID); + $store{$field} = \$args{serializer}{_uid}{user}{ $store{$field} }; } } elsif ($type eq "DelWatcher") { - my $principal = RT::Principal->new( RT->SystemUser ); - $principal->Load( $store{OldValue} ); - $store{OldValue} = \($principal->UID); + $store{OldValue} = \( join '-', 'RT::Principal', $RT::Organization, $store{OldValue} ); } elsif ($type eq "AddWatcher") { - my $principal = RT::Principal->new( RT->SystemUser ); - $principal->Load( $store{NewValue} ); - $store{NewValue} = \($principal->UID); + $store{NewValue} = \( join '-', 'RT::Principal', $RT::Organization, $store{NewValue} ); } elsif ($type eq "DeleteLink") { if ($store{OldValue}) { my $base = RT::URI->new( $self->CurrentUser ); @@ -2223,9 +2218,7 @@ sub Serialize { } } } elsif ($type =~ /^(Add|Open|Resolve)Reminder$/) { - my $ticket = RT::Ticket->new( RT->SystemUser ); - $ticket->Load( $store{NewValue} ); - $store{NewValue} = \($ticket->UID); + $store{NewValue} = \( join '-', 'RT::Ticket', $RT::Organization, $store{NewValue} ); } return %store; diff --git a/lib/RT/User.pm b/lib/RT/User.pm index 26a4692738..ea65b15b3a 100644 --- a/lib/RT/User.pm +++ b/lib/RT/User.pm @@ -3062,6 +3062,9 @@ sub BeforeWipeout { sub Serialize { my $self = shift; + my %args = @_; + $args{serializer}{_uid}{user}{ $self->Id } = $self->UID; + return ( Disabled => $self->PrincipalObj->Disabled, Principal => $self->PrincipalObj->UID, |