[Rt-commit] r9741 - rt/branches/3.6-RELEASE/lib/RT
ruz at bestpractical.com
ruz at bestpractical.com
Fri Nov 23 20:26:00 EST 2007
Author: ruz
Date: Fri Nov 23 20:25:55 2007
New Revision: 9741
Modified:
rt/branches/3.6-RELEASE/lib/RT/Users_Overlay.pm
Log:
* split WhoHaveRoleRights into more queries so buggy MySQL's
optimizer can do the right thing
Modified: rt/branches/3.6-RELEASE/lib/RT/Users_Overlay.pm
==============================================================================
--- rt/branches/3.6-RELEASE/lib/RT/Users_Overlay.pm (original)
+++ rt/branches/3.6-RELEASE/lib/RT/Users_Overlay.pm Fri Nov 23 20:25:55 2007
@@ -434,8 +434,7 @@
return (undef);
}
- my $from_role = $self->Clone;
- $from_role->WhoHaveRoleRight( %args );
+ my @from_role = $self->Clone->_WhoHaveRoleRightSplitted( %args );
my $from_group = $self->Clone;
$from_group->WhoHaveGroupRight( %args );
@@ -443,8 +442,8 @@
#XXX: DIRTY HACK
use DBIx::SearchBuilder::Union;
my $union = new DBIx::SearchBuilder::Union;
- $union->add($from_role);
- $union->add($from_group);
+ $union->add( $_ ) foreach @from_role;
+ $union->add( $from_group );
%$self = %$union;
bless $self, ref($union);
@@ -469,39 +468,48 @@
my $groups = $self->_JoinGroups( %args );
my $acl = $self->_JoinACL( %args );
- my ($check_roles, $check_objects) = ('','');
-
- my @objects = $self->_GetEquivObjects( %args );
- if ( @objects ) {
- my @role_clauses;
- my @object_clauses;
- foreach my $obj ( @objects ) {
- my $type = ref($obj)? ref($obj): $obj;
- my $id;
- $id = $obj->id if ref($obj) && UNIVERSAL::can($obj, 'id') && $obj->id;
-
- my $role_clause = "$groups.Domain = '$type-Role'";
- # XXX: Groups.Instance is VARCHAR in DB, we should quote value
- # if we want mysql 4.0 use indexes here. we MUST convert that
- # field to integer and drop this quotes.
- $role_clause .= " AND $groups.Instance = '$id'" if $id;
- push @role_clauses, "($role_clause)";
+ $self->Limit( ALIAS => $acl,
+ FIELD => 'PrincipalType',
+ VALUE => "$groups.Type",
+ QUOTEVALUE => 0,
+ );
- my $object_clause = "$acl.ObjectType = '$type'";
- $object_clause .= " AND $acl.ObjectId = $id" if $id;
- push @object_clauses, "($object_clause)";
- }
+ # no system user
+ $self->Limit( ALIAS => $self->PrincipalsAlias,
+ FIELD => 'id',
+ OPERATOR => '!=',
+ VALUE => $RT::SystemUser->id
+ );
- $check_roles .= join ' OR ', @role_clauses;
- $check_objects = join ' OR ', @object_clauses;
- } else {
- if( !$args{'IncludeSystemRights'} ) {
- $check_objects = "($acl.ObjectType != 'RT::System')";
+ my @objects = $self->_GetEquivObjects( %args );
+ unless ( @objects ) {
+ unless ( $args{'IncludeSystemRights'} ) {
+ $self->_AddSubClause( WhichObjects => "($acl.ObjectType != 'RT::System')" );
}
+ return;
}
- $self->_AddSubClause( "WhichObject", "($check_objects)" );
- $self->_AddSubClause( "WhichRole", "($check_roles)" );
+ my ($groups_clauses, $acl_clauses) = $self->_RoleClauses( $groups, $acl, @objects );
+ $self->_AddSubClause( "WhichObject", "(". join( ' OR ', @$groups_clauses ) .")" );
+ $self->_AddSubClause( "WhichRole", "(". join( ' OR ', @$acl_clauses ) .")" );
+
+ return;
+}
+
+sub _WhoHaveRoleRightSplitted {
+ my $self = shift;
+ my %args = (
+ Right => undef,
+ Object => undef,
+ IncludeSystemRights => undef,
+ IncludeSuperusers => undef,
+ IncludeSubgroupMembers => 1,
+ EquivObjects => [ ],
+ @_
+ );
+
+ my $groups = $self->_JoinGroups( %args );
+ my $acl = $self->_JoinACL( %args );
$self->Limit( ALIAS => $acl,
FIELD => 'PrincipalType',
@@ -515,7 +523,53 @@
OPERATOR => '!=',
VALUE => $RT::SystemUser->id
);
- return;
+
+ my @objects = $self->_GetEquivObjects( %args );
+ unless ( @objects ) {
+ unless ( $args{'IncludeSystemRights'} ) {
+ $self->_AddSubClause( WhichObjects => "($acl.ObjectType != 'RT::System')" );
+ }
+ return $self;
+ }
+
+ my ($groups_clauses, $acl_clauses) = $self->_RoleClauses( $groups, $acl, @objects );
+ $self->_AddSubClause( "WhichRole", "(". join( ' OR ', @$acl_clauses ) .")" );
+
+ my @res;
+ foreach ( @$groups_clauses ) {
+ my $tmp = $self->Clone;
+ $tmp->_AddSubClause( WhichObject => $_ );
+ push @res, $tmp;
+ }
+
+ return @res;
+}
+
+sub _RoleClauses {
+ my $self = shift;
+ my $groups = shift;
+ my $acl = shift;
+ my @objects = @_;
+
+ my @groups_clauses;
+ my @acl_clauses;
+ foreach my $obj ( @objects ) {
+ my $type = ref($obj)? ref($obj): $obj;
+ my $id;
+ $id = $obj->id if ref($obj) && UNIVERSAL::can($obj, 'id') && $obj->id;
+
+ my $role_clause = "$groups.Domain = '$type-Role'";
+ # XXX: Groups.Instance is VARCHAR in DB, we should quote value
+ # if we want mysql 4.0 use indexes here. we MUST convert that
+ # field to integer and drop this quotes.
+ $role_clause .= " AND $groups.Instance = '$id'" if $id;
+ push @groups_clauses, "($role_clause)";
+
+ my $object_clause = "$acl.ObjectType = '$type'";
+ $object_clause .= " AND $acl.ObjectId = $id" if $id;
+ push @acl_clauses, "($object_clause)";
+ }
+ return (\@groups_clauses, \@acl_clauses);
}
# XXX: should be generalized
More information about the Rt-commit
mailing list