diff options
author | Yorick Peterse <yorickpeterse@gmail.com> | 2016-12-06 17:31:58 +0100 |
---|---|---|
committer | Yorick Peterse <yorickpeterse@gmail.com> | 2016-12-19 17:11:03 +0100 |
commit | f73193c328b871a9a3af803012c10d9bc1bd0904 (patch) | |
tree | 016eafe1c321574b87b607325fd62e0f95779583 /app/models/user.rb | |
parent | a50cd9eb4b4392004e47e57b2fa37c12def5827f (diff) | |
download | gitlab-ce-f73193c328b871a9a3af803012c10d9bc1bd0904.tar.gz |
Smarter refreshing of authorized projectsproject-authorizations-diff
Prior to this commit the refreshing of authorized projects was done in
two steps:
1. Remove existing authorizations
2. Insert a new list of all authorizations
This can lead to a high amount of dead tuples as every time all rows are
being replaced. For example, if a user with 100 authorizations is given
access to a new project this would lead to:
* 100 rows being removed
* 101 new rows being inserted
This commit changes the way this system works so it only removes/inserts
what is necessary. Using the above example this would lead to only 1 new
row being inserted, with the initial 100 being left untouched.
Fixes https://gitlab.com/gitlab-org/gitlab-ce/issues/25257
Diffstat (limited to 'app/models/user.rb')
-rw-r--r-- | app/models/user.rb | 38 |
1 files changed, 10 insertions, 28 deletions
diff --git a/app/models/user.rb b/app/models/user.rb index 3a17c98eff6..9f5cc149361 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -443,22 +443,16 @@ class User < ActiveRecord::Base end def refresh_authorized_projects - transaction do - project_authorizations.delete_all - - # project_authorizations_union can return multiple records for the same - # project/user with different access_level so we take row with the maximum - # access_level - project_authorizations.connection.execute <<-SQL - INSERT INTO project_authorizations (user_id, project_id, access_level) - SELECT user_id, project_id, MAX(access_level) AS access_level - FROM (#{project_authorizations_union.to_sql}) sub - GROUP BY user_id, project_id - SQL - - unless authorized_projects_populated - update_column(:authorized_projects_populated, true) - end + Users::RefreshAuthorizedProjectsService.new(self).execute + end + + def remove_project_authorizations(project_ids) + project_authorizations.where(id: project_ids).delete_all + end + + def set_authorized_projects_column + unless authorized_projects_populated + update_column(:authorized_projects_populated, true) end end @@ -905,18 +899,6 @@ class User < ActiveRecord::Base private - # Returns a union query of projects that the user is authorized to access - def project_authorizations_union - relations = [ - personal_projects.select("#{id} AS user_id, projects.id AS project_id, #{Gitlab::Access::MASTER} AS access_level"), - groups_projects.select_for_project_authorization, - projects.select_for_project_authorization, - groups.joins(:shared_projects).select_for_project_authorization - ] - - Gitlab::SQL::Union.new(relations) - end - def ci_projects_union scope = { access_level: [Gitlab::Access::MASTER, Gitlab::Access::OWNER] } groups = groups_projects.where(members: scope) |