diff options
Diffstat (limited to 'lib/gitlab/analytics/cycle_analytics/records_fetcher.rb')
-rw-r--r-- | lib/gitlab/analytics/cycle_analytics/records_fetcher.rb | 54 |
1 files changed, 33 insertions, 21 deletions
diff --git a/lib/gitlab/analytics/cycle_analytics/records_fetcher.rb b/lib/gitlab/analytics/cycle_analytics/records_fetcher.rb index 178ebe0d4d4..b4752ed9e5b 100644 --- a/lib/gitlab/analytics/cycle_analytics/records_fetcher.rb +++ b/lib/gitlab/analytics/cycle_analytics/records_fetcher.rb @@ -31,14 +31,34 @@ module Gitlab @params = params @sort = params[:sort] || :end_event @direction = params[:direction] || :desc + @page = params[:page] || 1 + @per_page = MAX_RECORDS end + # rubocop: disable CodeReuse/ActiveRecord def serialized_records strong_memoize(:serialized_records) do # special case (legacy): 'Test' and 'Staging' stages should show Ci::Build records if default_test_stage? || default_staging_stage? + ci_build_join = mr_metrics_table + .join(build_table) + .on(mr_metrics_table[:pipeline_id].eq(build_table[:commit_id])) + .join_sources + + records = ordered_and_limited_query + .joins(ci_build_join) + .select(build_table[:id], *time_columns) + + yield records if block_given? + ci_build_records = preload_ci_build_associations(records) + AnalyticsBuildSerializer.new.represent(ci_build_records.map { |e| e['build'] }) else + records = ordered_and_limited_query.select(*columns, *time_columns) + + yield records if block_given? + records = preload_associations(records) + records.map do |record| project = record.project attributes = record.attributes.merge({ @@ -51,10 +71,11 @@ module Gitlab end end end + # rubocop: enable CodeReuse/ActiveRecord private - attr_reader :stage, :query, :params, :sort, :direction + attr_reader :stage, :query, :params, :sort, :direction, :page, :per_page def columns MAPPINGS.fetch(subject_class).fetch(:columns_for_select).map do |column_name| @@ -74,41 +95,32 @@ module Gitlab MAPPINGS.fetch(subject_class).fetch(:serializer_class).new end - # Loading Ci::Build records instead of MergeRequest records # rubocop: disable CodeReuse/ActiveRecord - def ci_build_records - ci_build_join = mr_metrics_table - .join(build_table) - .on(mr_metrics_table[:pipeline_id].eq(build_table[:commit_id])) - .join_sources - - q = ordered_and_limited_query - .joins(ci_build_join) - .select(build_table[:id], *time_columns) - - results = execute_query(q).to_a + def preload_ci_build_associations(records) + results = records.map(&:attributes) Gitlab::CycleAnalytics::Updater.update!(results, from: 'id', to: 'build', klass: ::Ci::Build.includes({ project: [:namespace], user: [], pipeline: [] })) end + # rubocop: enable CodeReuse/ActiveRecord def ordered_and_limited_query - order_by(query, sort, direction, columns).limit(MAX_RECORDS) + strong_memoize(:ordered_and_limited_query) do + order_by(query, sort, direction, columns).page(page).per(per_page).without_count + end end - def records - results = ordered_and_limited_query - .select(*columns, *time_columns) - + # rubocop: disable CodeReuse/ActiveRecord + def preload_associations(records) # using preloader instead of includes to avoid AR generating a large column list ActiveRecord::Associations::Preloader.new.preload( - results, + records, MAPPINGS.fetch(subject_class).fetch(:includes_for_query) ) - results + records end - # rubocop: enable CodeReuse/ActiveRecord + # rubocop: enable CodeReuse/ActiveRecord def time_columns [ stage.start_event.timestamp_projection.as('start_event_timestamp'), |