diff options
author | Stan Hu <stanhu@gmail.com> | 2019-03-27 09:22:23 +0300 |
---|---|---|
committer | Stan Hu <stanhu@gmail.com> | 2019-03-27 14:16:38 +0300 |
commit | 33a4fe1f460f64f2c9f56c8f8874982dc45effd2 (patch) | |
tree | e6d79d35ac2f26688e77938f3474416fde37e59e /app | |
parent | c408be48ca3d6840076c6f16c7910411cdfca24c (diff) |
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.
Diffstat (limited to 'app')
-rw-r--r-- | app/models/project.rb | 27 |
1 files 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", |