summaryrefslogtreecommitdiff
path: root/app/models/user.rb
diff options
context:
space:
mode:
authorYorick Peterse <yorickpeterse@gmail.com>2016-12-06 17:31:58 +0100
committerYorick Peterse <yorickpeterse@gmail.com>2016-12-19 17:11:03 +0100
commitf73193c328b871a9a3af803012c10d9bc1bd0904 (patch)
tree016eafe1c321574b87b607325fd62e0f95779583 /app/models/user.rb
parenta50cd9eb4b4392004e47e57b2fa37c12def5827f (diff)
downloadgitlab-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.rb38
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)