Commit d8e504a8 authored by Bob Van Landuyt's avatar Bob Van Landuyt

Use Arel to build preloaded counts

parent 18907efb
module LoadedInGroupList module LoadedInGroupList
extend ActiveSupport::Concern extend ActiveSupport::Concern
PROJECT_COUNT_SQL = <<~PROJECTCOUNT.freeze
SELECT COUNT(*) AS preloaded_project_count
FROM projects
WHERE projects.namespace_id = namespaces.id
PROJECTCOUNT
SUBGROUP_COUNT_SQL = <<~SUBGROUPCOUNT.freeze
(SELECT COUNT(*) AS preloaded_subgroup_count
FROM namespaces children
WHERE children.parent_id = namespaces.id)
SUBGROUPCOUNT
MEMBER_COUNT_SQL = <<~MEMBERCOUNT.freeze
(SELECT COUNT(*) AS preloaded_member_count
FROM members
WHERE members.source_type = 'Namespace'
AND members.source_id = namespaces.id
AND members.requested_at IS NULL)
MEMBERCOUNT
COUNT_SELECTS = ['namespaces.*',
SUBGROUP_COUNT_SQL,
MEMBER_COUNT_SQL].freeze
module ClassMethods module ClassMethods
def with_counts(archived:) def with_counts(archived:)
selects = COUNT_SELECTS.dup << project_count(archived) selects_including_counts = [
select(selects) 'namespaces.*',
"(#{project_count_sql(archived).to_sql})",
"(#{subgroup_count_sql.to_sql})",
"(#{member_count_sql.to_sql})"
]
select(selects_including_counts)
end end
def with_selects_for_list(archived: nil) def with_selects_for_list(archived: nil)
with_route.with_counts(archived: archived) with_route.with_counts(archived: archived)
end end
def project_count(archived) private
project_count = if archived == 'only'
PROJECT_COUNT_SQL + 'AND projects.archived IS true' def project_count_sql(archived = nil)
projects = Project.arel_table
namespaces = Namespace.arel_table
base_count = projects.project(Arel.star.count.as('preloaded_project_count'))
.where(projects[:namespace_id].eq(namespaces[:id]))
if archived == 'only'
base_count.where(projects[:archived].eq(true))
elsif Gitlab::Utils.to_boolean(archived) elsif Gitlab::Utils.to_boolean(archived)
PROJECT_COUNT_SQL base_count
else else
PROJECT_COUNT_SQL + 'AND projects.archived IS NOT true' base_count.where(projects[:archived].not_eq(true))
end end
"(#{project_count})" end
def subgroup_count_sql
namespaces = Namespace.arel_table
children = namespaces.alias('children')
namespaces.project(Arel.star.count.as('preloaded_subgroup_count'))
.from(children)
.where(children[:parent_id].eq(namespaces[:id]))
end
def member_count_sql
members = Member.arel_table
namespaces = Namespace.arel_table
members.project(Arel.star.count.as('preloaded_member_count'))
.where(members[:source_type].eq(Namespace.name))
.where(members[:source_id].eq(namespaces[:id]))
.where(members[:requested_at].eq(nil))
end end
end end
...@@ -50,26 +59,14 @@ module LoadedInGroupList ...@@ -50,26 +59,14 @@ module LoadedInGroupList
end end
def project_count def project_count
@project_count ||= if respond_to?(:preloaded_project_count) @project_count ||= try(:preloaded_project_count) || projects.non_archived.count
preloaded_project_count
else
projects.non_archived.count
end
end end
def subgroup_count def subgroup_count
@subgroup_count ||= if respond_to?(:preloaded_subgroup_count) @subgroup_count ||= try(:preloaded_subgroup_count) || children.count
preloaded_subgroup_count
else
children.count
end
end end
def member_count def member_count
@member_count ||= if respond_to?(:preloaded_member_count) @member_count ||= try(:preloaded_member_count) || users.count
preloaded_member_count
else
users.count
end
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment