From 33a4fe1f460f64f2c9f56c8f8874982dc45effd2 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Wed, 27 Mar 2019 01:22:23 -0500 Subject: Skip querying for private projects if they are not requested If the requested visibility levels contains only public and/or internal, omitting private, then we can skip the EXISTS query to search for private projects for the user. --- app/models/project.rb | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/app/models/project.rb b/app/models/project.rb index 6667076b359..06010409574 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -471,14 +471,29 @@ class Project < ActiveRecord::Base return public_to_user unless user visible_levels = Gitlab::VisibilityLevel.levels_for_user(user) - visible_levels &= Array(requested_visibility_levels) if requested_visibility_levels.present? + include_private = true + requested_visibility_levels = Array(requested_visibility_levels) - if visible_levels.present? - where('EXISTS (?) OR projects.visibility_level IN (?)', - user.authorizations_for_projects, visible_levels) - else - where('EXISTS (?)', user.authorizations_for_projects) + if requested_visibility_levels.present? + visible_levels &= requested_visibility_levels + include_private = requested_visibility_levels.include?(Gitlab::VisibilityLevel::PRIVATE) end + + public_or_internal_rel = + if visible_levels.present? + where('projects.visibility_level IN (?)', visible_levels) + else + Project.none + end + + private_rel = + if include_private + where('EXISTS (?)', user.authorizations_for_projects) + else + Project.none + end + + public_or_internal_rel.or(private_rel) end # project features may be "disabled", "internal", "enabled" or "public". If "internal", -- cgit v1.2.1