diff options
Diffstat (limited to 'lib/gitlab/analytics/cycle_analytics')
-rw-r--r-- | lib/gitlab/analytics/cycle_analytics/base_query_builder.rb | 56 | ||||
-rw-r--r-- | lib/gitlab/analytics/cycle_analytics/median.rb | 4 | ||||
-rw-r--r-- | lib/gitlab/analytics/cycle_analytics/records_fetcher.rb | 20 |
3 files changed, 31 insertions, 49 deletions
diff --git a/lib/gitlab/analytics/cycle_analytics/base_query_builder.rb b/lib/gitlab/analytics/cycle_analytics/base_query_builder.rb index 9ea20a4d6a4..4dec71b35e8 100644 --- a/lib/gitlab/analytics/cycle_analytics/base_query_builder.rb +++ b/lib/gitlab/analytics/cycle_analytics/base_query_builder.rb @@ -8,21 +8,24 @@ module Gitlab delegate :subject_class, to: :stage - # rubocop: disable CodeReuse/ActiveRecord + FINDER_CLASSES = { + MergeRequest.to_s => MergeRequestsFinder, + Issue.to_s => IssuesFinder + }.freeze def initialize(stage:, params: {}) @stage = stage - @params = params + @params = build_finder_params(params) end + # rubocop: disable CodeReuse/ActiveRecord def build - query = subject_class - query = filter_by_parent_model(query) - query = filter_by_time_range(query) + query = finder.execute query = stage.start_event.apply_query_customization(query) query = stage.end_event.apply_query_customization(query) query.where(duration_condition) end + # rubocop: enable CodeReuse/ActiveRecord private @@ -32,38 +35,33 @@ module Gitlab stage.end_event.timestamp_projection.gteq(stage.start_event.timestamp_projection) end - def filter_by_parent_model(query) - if parent_class.eql?(Project) - if subject_class.eql?(Issue) - query.where(project_id: stage.parent_id) - elsif subject_class.eql?(MergeRequest) - query.where(target_project_id: stage.parent_id) - else - raise ArgumentError, "unknown subject_class: #{subject_class}" - end - else - raise ArgumentError, "unknown parent_class: #{parent_class}" - end + def finder + FINDER_CLASSES.fetch(subject_class.to_s).new(params[:current_user], params) end - def filter_by_time_range(query) - from = params.fetch(:from, 30.days.ago) - to = params[:to] - - query = query.where(subject_table[:created_at].gteq(from)) - query = query.where(subject_table[:created_at].lteq(to)) if to - query + def parent_class + stage.parent.class end - def subject_table - subject_class.arel_table + def build_finder_params(params) + {}.tap do |finder_params| + finder_params[:current_user] = params[:current_user] + + add_parent_model_params!(finder_params) + add_time_range_params!(finder_params, params[:from], params[:to]) + end end - def parent_class - stage.parent.class + def add_parent_model_params!(finder_params) + raise(ArgumentError, "unknown parent_class: #{parent_class}") unless parent_class.eql?(Project) + + finder_params[:project_id] = stage.parent_id end - # rubocop: enable CodeReuse/ActiveRecord + def add_time_range_params!(finder_params, from, to) + finder_params[:created_after] = from || 30.days.ago + finder_params[:created_before] = to if to + end end end end diff --git a/lib/gitlab/analytics/cycle_analytics/median.rb b/lib/gitlab/analytics/cycle_analytics/median.rb index 9fcaeadf351..6c0450ac9e5 100644 --- a/lib/gitlab/analytics/cycle_analytics/median.rb +++ b/lib/gitlab/analytics/cycle_analytics/median.rb @@ -11,12 +11,14 @@ module Gitlab @query = query end + # rubocop: disable CodeReuse/ActiveRecord def seconds - @query = @query.select(median_duration_in_seconds.as('median')) + @query = @query.select(median_duration_in_seconds.as('median')).reorder(nil) result = execute_query(@query).first || {} result['median'] || nil end + # rubocop: enable CodeReuse/ActiveRecord def days seconds ? seconds.fdiv(1.day) : nil diff --git a/lib/gitlab/analytics/cycle_analytics/records_fetcher.rb b/lib/gitlab/analytics/cycle_analytics/records_fetcher.rb index e8e269a88f0..e7352a23b99 100644 --- a/lib/gitlab/analytics/cycle_analytics/records_fetcher.rb +++ b/lib/gitlab/analytics/cycle_analytics/records_fetcher.rb @@ -12,13 +12,11 @@ module Gitlab MAPPINGS = { Issue => { - finder_class: IssuesFinder, serializer_class: AnalyticsIssueSerializer, includes_for_query: { project: [:namespace], author: [] }, columns_for_select: %I[title iid id created_at author_id project_id] }, MergeRequest => { - finder_class: MergeRequestsFinder, serializer_class: AnalyticsMergeRequestSerializer, includes_for_query: { target_project: [:namespace], author: [] }, columns_for_select: %I[title iid id created_at author_id state_id target_project_id] @@ -56,27 +54,12 @@ module Gitlab attr_reader :stage, :query, :params - def finder_query - MAPPINGS - .fetch(subject_class) - .fetch(:finder_class) - .new(params.fetch(:current_user), finder_params.fetch(stage.parent.class)) - .execute - end - def columns MAPPINGS.fetch(subject_class).fetch(:columns_for_select).map do |column_name| subject_class.arel_table[column_name] end end - # EE will override this to include Group rules - def finder_params - { - Project => { project_id: stage.parent_id } - } - end - def default_test_stage? stage.matches_with_stage_params?(Gitlab::Analytics::CycleAnalytics::DefaultStages.params_for_test_stage) end @@ -113,8 +96,7 @@ module Gitlab end def records - results = finder_query - .merge(ordered_and_limited_query) + results = ordered_and_limited_query .select(*columns, round_duration_to_seconds.as('total_time')) # using preloader instead of includes to avoid AR generating a large column list |