summaryrefslogtreecommitdiff
path: root/lib/gitlab/cycle_analytics/base_stage.rb
blob: afec16d18183e2f0b6bfd588581a763e0991a65e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
module Gitlab
  module CycleAnalytics
    class BaseStage
      include BaseQuery

      def initialize(project:, options:)
        @project = project
        @options = options
      end

      def event
        @event ||= Gitlab::CycleAnalytics::Event[name].new(project: @project,
                                                           stage: name,
                                                           options: event_options)
      end

      def events
        event.fetch
      end

      def median_data
        AnalyticsStageSerializer.new.represent(self).as_json
      end

      def title
        name.to_s.capitalize
      end

      def median
        cte_table = Arel::Table.new("cte_table_for_#{name}")

        # Build a `SELECT` query. We find the first of the `end_time_attrs` that isn't `NULL` (call this end_time).
        # Next, we find the first of the start_time_attrs that isn't `NULL` (call this start_time).
        # We compute the (end_time - start_time) interval, and give it an alias based on the current
        # cycle analytics stage.
        interval_query = Arel::Nodes::As.new(
          cte_table,
          subtract_datetimes(base_query, @start_time_attrs, @end_time_attrs, name.to_s))

        median_datetime(cte_table, interval_query, name)
      end

      def name
        raise NotImplementedError.new("Expected #{self.name} to implement name")
      end

      private

      def event_options
        @options.merge(start_time_attrs: @start_time_attrs, end_time_attrs: @end_time_attrs)
      end
    end
  end
end