Class: Gitlab::Analytics::CycleAnalytics::Aggregated::RecordsFetcher

Inherits:
Object
  • Object
show all
Includes:
StageQueryHelpers, Utils::StrongMemoize
Defined in:
lib/gitlab/analytics/cycle_analytics/aggregated/records_fetcher.rb

Constant Summary collapse

MAX_RECORDS =
20
MAPPINGS =
{
  Issue => {
    serializer_class: AnalyticsIssueSerializer,
    includes_for_query: { project: { namespace: [:route] }, author: [] },
    columns_for_select: %I[title iid id created_at author_id project_id]
  },
  MergeRequest => {
    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]
  }
}.freeze

Instance Method Summary collapse

Methods included from StageQueryHelpers

#duration, #end_event_timestamp_projection, #execute_query, #in_progress?, #order_by, #requires_grouping?, #round_duration_to_seconds, #zero_interval

Constructor Details

#initialize(stage:, query:, params: {}) ⇒ RecordsFetcher

Returns a new instance of RecordsFetcher.



26
27
28
29
30
31
32
33
34
35
# File 'lib/gitlab/analytics/cycle_analytics/aggregated/records_fetcher.rb', line 26

def initialize(stage:, query:, params: {})
  @stage = stage
  @query = query
  @params = params
  @sort = params[:sort] || :end_event
  @direction = params[:direction] || :desc
  @page = params[:page] || 1
  @per_page = MAX_RECORDS
  @stage_event_model = query.model
end

Instance Method Details

#limited_queryObject



67
68
69
70
71
72
# File 'lib/gitlab/analytics/cycle_analytics/aggregated/records_fetcher.rb', line 67

def limited_query
  query
    .page(page)
    .per(per_page)
    .without_count
end

#serialized_recordsObject



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/gitlab/analytics/cycle_analytics/aggregated/records_fetcher.rb', line 37

def serialized_records
  strong_memoize(:serialized_records) do
    # When RecordsFetcher is used with query sourced from
    # InOperatorOptimization::QueryBuilder only columns
    # used in ORDER BY statement would be selected by Arel.star operation
    selections = [stage_event_model.arel_table[Arel.star]]
    selections << duration_in_seconds.as('total_time') if params[:sort] != :duration # duration sorting already exposes this data

    records = limited_query.select(*selections)

    yield records if block_given?
    issuables_and_records = load_issuables(records)

    preload_associations(issuables_and_records.map(&:first))

    issuables_and_records.map do |issuable, record|
      project = issuable.project
      attributes = issuable.attributes.merge({
        project_path: project.path,
        namespace_path: project.namespace.route.path,
        author: issuable.author,
        total_time: record.total_time,
        start_event_timestamp: record.start_event_timestamp,
        end_event_timestamp: record.end_event_timestamp
      })
      serializer.represent(attributes)
    end
  end
end