Skip to content

Commit 492a03a

Browse files
Merge branch '5.0/speed-up-importer' into 5.0-trunk
2 parents 8d71c5c + c74b9aa commit 492a03a

17 files changed

Lines changed: 788 additions & 171 deletions

lib/RT/ACE.pm

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,8 @@ If it's the system object, returns undef.
523523
524524
If the user has no rights, returns undef.
525525
526+
CAVEAT: the returned object is cached, reload it to get the latest data.
527+
526528
=cut
527529

528530

@@ -531,16 +533,17 @@ If the user has no rights, returns undef.
531533
sub Object {
532534
my $self = shift;
533535

534-
my $appliesto_obj;
536+
return $self->{_cached}{Object} if $self->{_cached}{Object};
535537

536-
if ($self->__Value('ObjectType') && $self->__Value('ObjectType')->DOES('RT::Record::Role::Rights') ) {
537-
$appliesto_obj = $self->__Value('ObjectType')->new($self->CurrentUser);
538-
unless (ref( $appliesto_obj) eq $self->__Value('ObjectType')) {
538+
if ( $self->__Value('ObjectType') && $self->__Value('ObjectType')->DOES('RT::Record::Role::Rights') ) {
539+
my $appliesto_obj = $self->__Value('ObjectType')->new( $self->CurrentUser );
540+
unless ( ref($appliesto_obj) eq $self->__Value('ObjectType') ) {
539541
return undef;
540542
}
541543
$appliesto_obj->Load( $self->__Value('ObjectId') );
542-
return ($appliesto_obj);
543-
}
544+
$self->{_cached}{Object} = $appliesto_obj;
545+
return $self->{_cached}{Object};
546+
}
544547
else {
545548
$RT::Logger->warning( "$self -> Object called for an object "
546549
. "of an unknown type:"
@@ -555,20 +558,22 @@ sub Object {
555558
556559
Returns the RT::Principal object for this ACE.
557560
561+
CAVEAT: the returned object is cached, reload it to get the latest data.
562+
558563
=cut
559564

560565
sub PrincipalObj {
561566
my $self = shift;
562567

563-
my $princ_obj = RT::Principal->new( $self->CurrentUser );
564-
$princ_obj->Load( $self->__Value('PrincipalId') );
568+
unless ( $self->{_cached}{PrincipalObj} ) {
569+
$self->{_cached}{PrincipalObj} = RT::Principal->new( $self->CurrentUser );
570+
$self->{_cached}{PrincipalObj}->Load( $self->__Value('PrincipalId') );
565571

566-
unless ( $princ_obj->Id ) {
567-
$RT::Logger->err(
568-
"ACE " . $self->Id . " couldn't load its principal object" );
572+
unless ( $self->{_cached}{PrincipalObj}->Id ) {
573+
$RT::Logger->err( "ACE " . $self->Id . " couldn't load its principal object" );
574+
}
569575
}
570-
return ($princ_obj);
571-
576+
return $self->{_cached}{PrincipalObj};
572577
}
573578

574579

@@ -583,6 +588,7 @@ sub _Set {
583588

584589
sub _Value {
585590
my $self = shift;
591+
return $self->__Value(@_) if $self->CurrentUser->Id == RT->SystemUser->Id;
586592

587593
if ( $self->PrincipalObj->IsGroup
588594
&& $self->PrincipalObj->Object->HasMemberRecursively(

lib/RT/Attachment.pm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,6 +1070,8 @@ Returns its value as a string, if the user passes an ACL check
10701070

10711071
sub _Value {
10721072
my $self = shift;
1073+
return $self->__Value(@_) if $self->CurrentUser->Id == RT->SystemUser->Id;
1074+
10731075
my $field = shift;
10741076

10751077
#if the field is public, return it.

lib/RT/Attachments.pm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ sub AddRecord {
248248
my $self = shift;
249249
my ($record) = @_;
250250

251-
return unless $record->TransactionObj->CurrentUserCanSee;
251+
return unless $self->CurrentUser->Id == RT->SystemUser->Id || $record->TransactionObj->CurrentUserCanSee;
252252
return $self->SUPER::AddRecord( $record );
253253
}
254254

lib/RT/Attribute.pm

Lines changed: 73 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -389,20 +389,28 @@ sub SetSubValues {
389389

390390
}
391391

392+
=head2 Object
392393
393-
sub Object {
394-
my $self = shift;
395-
my $object_type = $self->__Value('ObjectType');
396-
my $object;
397-
eval { $object = $object_type->new($self->CurrentUser) };
398-
unless(UNIVERSAL::isa($object, $object_type)) {
399-
$RT::Logger->error("Attribute ".$self->Id." has a bogus object type - $object_type (".$@.")");
400-
return(undef);
401-
}
402-
$object->Load($self->__Value('ObjectId'));
394+
Returns the object current attribute blongs to.
403395
404-
return($object);
396+
CAVEAT: the returned object is cached, reload it to get the latest data.
397+
398+
=cut
405399

400+
sub Object {
401+
my $self = shift;
402+
unless ( $self->{_cached}{Object} ) {
403+
my $object_type = $self->__Value('ObjectType');
404+
my $object;
405+
eval { $object = $object_type->new( $self->CurrentUser ) };
406+
unless ( UNIVERSAL::isa( $object, $object_type ) ) {
407+
$RT::Logger->error( "Attribute " . $self->Id . " has a bogus object type - $object_type (" . $@ . ")" );
408+
return (undef);
409+
}
410+
$object->Load( $self->__Value('ObjectId') );
411+
$self->{_cached}{Object} = $object;
412+
}
413+
return $self->{_cached}{Object};
406414
}
407415

408416

@@ -1031,6 +1039,22 @@ sub PostInflateFixup {
10311039
}
10321040
elsif ($self->Name eq 'Subscription') {
10331041
my $content = $self->Content;
1042+
for my $type ( qw/Users Groups/ ) {
1043+
if ( my $list = $content->{Recipients}{$type} ) {
1044+
my @ids;
1045+
for my $item ( @$list ) {
1046+
if ( ref $item eq 'SCALAR' ) {
1047+
my $obj = $importer->LookupObj($$item);
1048+
push @ids, $obj->Id if $obj && $obj->Id;
1049+
}
1050+
else {
1051+
push @ids, $item;
1052+
}
1053+
}
1054+
@$list = @ids;
1055+
}
1056+
}
1057+
10341058
if (ref($content->{DashboardId}) eq 'SCALAR') {
10351059
my $attr = $importer->LookupObj(${ $content->{DashboardId} });
10361060
if ($attr) {
@@ -1046,6 +1070,17 @@ sub PostInflateFixup {
10461070
}
10471071
$self->SetContent( $content, SyncLinks => 0, RecordTransaction => 0 );
10481072
}
1073+
elsif ( $self->Name eq 'Bookmarks' ) {
1074+
my $content = $self->Content;
1075+
my @ids;
1076+
for my $uid (@$content) {
1077+
if ( my $ticket = $importer->LookupObj($$uid) ) {
1078+
push @ids, $ticket->Id;
1079+
}
1080+
}
1081+
$content = { map { $_ => 1 } @ids };
1082+
$self->SetContent($content);
1083+
}
10491084
}
10501085

10511086
sub PostInflate {
@@ -1069,28 +1104,21 @@ sub Serialize {
10691104
my $content = $self->_DeserializeContent($store{Content});
10701105
for my $pane (values %{ $content || {} }) {
10711106
for (@$pane) {
1072-
my $attr = RT::Attribute->new($self->CurrentUser);
1073-
$attr->LoadById($_);
1074-
$_ = \($attr->UID);
1107+
$_ = \( join '-', 'RT::Attribute', $RT::Organization, $_ );
10751108
}
10761109
}
10771110
$store{Content} = $self->_SerializeContent($content);
10781111
}
10791112
elsif ( $store{Name} =~ /DefaultDashboard$/ ) {
1080-
my $content = $store{Content};
1081-
my $attr = RT::Attribute->new( $self->CurrentUser );
1082-
$attr->LoadById($content);
1083-
$store{Content} = \$attr->UID;
1113+
$store{Content} = \( join '-', 'RT::Attribute', $RT::Organization, $store{Content} );
10841114
}
10851115
# encode saved searches and dashboards to be UIDs
10861116
elsif ($store{Name} eq 'Dashboard') {
10871117
my $content = $self->_DeserializeContent($store{Content}) || {};
10881118
for my $pane (values %{ $content->{Panes} || {} }) {
10891119
for (@$pane) {
10901120
if ($_->{portlet_type} eq 'search' || $_->{portlet_type} eq 'dashboard') {
1091-
my $attr = RT::Attribute->new($self->CurrentUser);
1092-
$attr->LoadById($_->{id});
1093-
$_->{uid} = \($attr->UID);
1121+
$_->{uid} = \( join '-', 'RT::Attribute', $RT::Organization, $_->{id} );
10941122
}
10951123
# pass through everything else (e.g. component)
10961124
}
@@ -1100,9 +1128,30 @@ sub Serialize {
11001128
# encode subscriptions to have dashboard UID
11011129
elsif ($store{Name} eq 'Subscription') {
11021130
my $content = $self->_DeserializeContent($store{Content});
1103-
my $attr = RT::Attribute->new($self->CurrentUser);
1104-
$attr->LoadById($content->{DashboardId});
1105-
$content->{DashboardId} = \($attr->UID);
1131+
$content->{DashboardId} = \( join '-', 'RT::Attribute', $RT::Organization, $content->{DashboardId} );
1132+
1133+
# encode user/groups to be UIDs
1134+
for my $type (qw/Users Groups/) {
1135+
if ( $content->{Recipients}{$type} ) {
1136+
my $class = $type eq 'Users' ? 'RT::User' : 'RT::Group';
1137+
my @uids;
1138+
for my $id ( @{ $content->{Recipients}{$type} } ) {
1139+
my $obj = $class->new( RT->SystemUser );
1140+
$obj->Load($id);
1141+
if ( $obj->Id ) {
1142+
push @uids,
1143+
\( join '-', $class, $class eq 'RT::User' ? $obj->Name : ( $RT::Organization, $obj->Id ) );
1144+
}
1145+
}
1146+
$content->{Recipients}{$type} = \@uids;
1147+
}
1148+
}
1149+
1150+
$store{Content} = $self->_SerializeContent($content);
1151+
}
1152+
elsif ( $self->Name eq 'Bookmarks' ) {
1153+
my $content = $self->Content;
1154+
$content = [ map { \( join '-', 'RT::Ticket', $RT::Organization, $_ ) } keys %$content ];
11061155
$store{Content} = $self->_SerializeContent($content);
11071156
}
11081157

lib/RT/Group.pm

Lines changed: 44 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,9 +1335,16 @@ The response is cached. PrincipalObj should never ever change.
13351335

13361336
sub PrincipalObj {
13371337
my $self = shift;
1338-
my $res = RT::Principal->new( $self->CurrentUser );
1339-
$res->Load( $self->id );
1340-
return $res;
1338+
unless ( $self->{_cached}{PrincipalObj} && $self->{_cached}{PrincipalObj}->Id ) {
1339+
$self->{_cached}{PrincipalObj} = RT::Principal->new( $self->CurrentUser );
1340+
if ( $self->Id ) {
1341+
my ( $ret, $msg ) = $self->{_cached}{PrincipalObj}->Load( $self->id );
1342+
if ( !$ret ) {
1343+
RT->Logger->warning( "Couldn't load principal #" . $self->id . ": $msg" );
1344+
}
1345+
}
1346+
}
1347+
return $self->{_cached}{PrincipalObj};
13411348
}
13421349

13431350

@@ -1355,6 +1362,15 @@ sub PrincipalId {
13551362
sub InstanceObj {
13561363
my $self = shift;
13571364

1365+
my $class = $self->InstanceClass or return;
1366+
1367+
my $obj = $class->new( $self->CurrentUser );
1368+
$obj->Load( $self->Instance );
1369+
return $obj;
1370+
}
1371+
1372+
sub InstanceClass {
1373+
my $self = shift;
13581374
my $class;
13591375
if ( $self->Domain eq 'ACLEquivalence' ) {
13601376
$class = "RT::User";
@@ -1365,12 +1381,7 @@ sub InstanceObj {
13651381
} elsif ($self->Domain eq 'RT::Asset-Role') {
13661382
$class = "RT::Asset";
13671383
}
1368-
1369-
return unless $class;
1370-
1371-
my $obj = $class->new( $self->CurrentUser );
1372-
$obj->Load( $self->Instance );
1373-
return $obj;
1384+
return $class;
13741385
}
13751386

13761387
sub BasicColumns {
@@ -1670,8 +1681,18 @@ sub Serialize {
16701681
my %args = (@_);
16711682
my %store = $self->SUPER::Serialize(@_);
16721683

1673-
my $instance = $self->InstanceObj;
1674-
$store{Instance} = \($instance->UID) if $instance;
1684+
if ( my $class = $self->InstanceClass ) {
1685+
if ( $class->can('UID') eq RT::Record->can('UID') ) {
1686+
$store{Instance} = \( join '-', $class, $RT::Organization, $store{Instance} );
1687+
}
1688+
elsif ( $class eq 'RT::User' ) {
1689+
$store{Instance} = \$args{serializer}{_uid}{user}{ $store{Instance} };
1690+
}
1691+
else {
1692+
my $instance = $self->InstanceObj;
1693+
$store{Instance} = \($instance->UID);
1694+
}
1695+
}
16751696

16761697
$store{Disabled} = $self->PrincipalObj->Disabled;
16771698
$store{Principal} = $self->PrincipalObj->UID;
@@ -1742,30 +1763,22 @@ sub PreInflate {
17421763
return $duplicated->() if $obj->Id;
17431764
}
17441765

1745-
my $principal = RT::Principal->new( RT->SystemUser );
1746-
my ($id) = $principal->Create(
1747-
PrincipalType => 'Group',
1748-
Disabled => $disabled,
1749-
);
1750-
1751-
# Now we have a principal id, set the id for the group record
1752-
$data->{id} = $id;
1766+
# serialized data with --all has principals, in which case we don't need to create a new one.
1767+
my $principal_obj = $importer->LookupObj( $principal_uid );
1768+
if ( $principal_obj ) {
1769+
$data->{id} = $principal_obj->Id;
1770+
}
1771+
else {
1772+
my $id = $importer->NextPrincipalId( PrincipalType => 'Group', Disabled => $disabled );
17531773

1754-
$importer->Resolve( $principal_uid => ref($principal), $id );
1755-
$data->{id} = $id;
1774+
# Now we have a principal id, set the id for the group record
1775+
$data->{id} = $id;
17561776

1757-
return 1;
1758-
}
1777+
$importer->Resolve( $principal_uid => 'RT::Principal', $id );
1778+
}
17591779

1760-
sub PostInflate {
1761-
my $self = shift;
17621780

1763-
my $cgm = RT::CachedGroupMember->new($self->CurrentUser);
1764-
$cgm->Create(
1765-
Group => $self->PrincipalObj,
1766-
Member => $self->PrincipalObj,
1767-
ImmediateParent => $self->PrincipalObj
1768-
);
1781+
return 1;
17691782
}
17701783

17711784
# If this group represents the members of a custom role, then return

lib/RT/GroupMember.pm

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -603,12 +603,6 @@ sub PreInflate {
603603
return 1;
604604
}
605605

606-
sub PostInflate {
607-
my $self = shift;
608-
609-
$self->_InsertCGM;
610-
}
611-
612606
RT::Base->_ImportOverlays();
613607

614608
1;

0 commit comments

Comments
 (0)