Commit 5e9b0c12 authored by Heinrich Lee Yu's avatar Heinrich Lee Yu

Simplify calendar.json query

Group the rows once outside the UNION so that we return totals and we
don't have to aggregate in Ruby
parent a9a8dd14
...@@ -23,25 +23,28 @@ module Gitlab ...@@ -23,25 +23,28 @@ module Gitlab
def activity_dates def activity_dates
return @activity_dates if @activity_dates.present? return @activity_dates if @activity_dates.present?
date_interval = "INTERVAL '#{@contributor_time_instance.now.utc_offset} seconds'"
# Can't use Event.contributions here because we need to check 3 different # Can't use Event.contributions here because we need to check 3 different
# project_features for the (currently) 3 different contribution types # project_features for the (currently) 3 different contribution types
date_from = @contributor_time_instance.now.years_ago(1) date_from = @contributor_time_instance.now.years_ago(1)
repo_events = event_counts(date_from, :repository) repo_events = event_created_at(date_from, :repository)
.having(action: :pushed) .where(action: :pushed)
issue_events = event_counts(date_from, :issues) issue_events = event_created_at(date_from, :issues)
.having(action: [:created, :closed], target_type: "Issue") .where(action: [:created, :closed], target_type: "Issue")
mr_events = event_counts(date_from, :merge_requests) mr_events = event_created_at(date_from, :merge_requests)
.having(action: [:merged, :created, :closed], target_type: "MergeRequest") .where(action: [:merged, :created, :closed], target_type: "MergeRequest")
note_events = event_counts(date_from, :merge_requests) note_events = event_created_at(date_from, :merge_requests)
.having(action: :commented) .where(action: :commented)
events = Event events = Event
.select(:project_id, :target_type, :action, :date, :total_amount) .select("date(created_at + #{date_interval}) AS date", 'COUNT(*) AS num_events')
.from_union([repo_events, issue_events, mr_events, note_events]) .from_union([repo_events, issue_events, mr_events, note_events], remove_duplicates: false)
.group(:date)
.map(&:attributes) .map(&:attributes)
@activity_dates = events.each_with_object(Hash.new {|h, k| h[k] = 0 }) do |event, activities| @activity_dates = events.each_with_object(Hash.new {|h, k| h[k] = 0 }) do |event, activities|
activities[event["date"]] += event["total_amount"] activities[event["date"]] += event["num_events"]
end end
end end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
...@@ -74,7 +77,7 @@ module Gitlab ...@@ -74,7 +77,7 @@ module Gitlab
end end
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def event_counts(date_from, feature) def event_created_at(date_from, feature)
t = Event.arel_table t = Event.arel_table
# re-running the contributed projects query in each union is expensive, so # re-running the contributed projects query in each union is expensive, so
...@@ -90,11 +93,8 @@ module Gitlab ...@@ -90,11 +93,8 @@ module Gitlab
.and(t[:created_at].lteq(@contributor_time_instance.today.end_of_day)) .and(t[:created_at].lteq(@contributor_time_instance.today.end_of_day))
.and(t[:author_id].eq(contributor.id)) .and(t[:author_id].eq(contributor.id))
date_interval = "INTERVAL '#{@contributor_time_instance.now.utc_offset} seconds'"
Event.reorder(nil) Event.reorder(nil)
.select(t[:project_id], t[:target_type], t[:action], "date(created_at + #{date_interval}) AS date", 'count(id) as total_amount') .select(:created_at)
.group(t[:project_id], t[:target_type], t[:action], "date(created_at + #{date_interval})")
.where(conditions) .where(conditions)
.where("events.project_id in (#{authed_projects.to_sql})") # rubocop:disable GitlabSecurity/SqlInjection .where("events.project_id in (#{authed_projects.to_sql})") # rubocop:disable GitlabSecurity/SqlInjection
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