Read about our upcoming Code of Conduct on this issue

This instance will be upgraded to Heptapod 0.28.1 on 2022-01-26 at 16:00 UTC+1 (a few minutes of down time)

charts.rb 3.36 KB
Newer Older
1
2
# frozen_string_literal: true

3
4
5
6
module Gitlab
  module Ci
    module Charts
      module DailyInterval
7
        # rubocop: disable CodeReuse/ActiveRecord
8
9
        def grouped_count(query)
          query
Maxim Rydkin's avatar
Maxim Rydkin committed
10
            .group("DATE(#{::Ci::Pipeline.table_name}.created_at)")
11
            .count(:created_at)
12
            .transform_keys { |date| date.strftime(@format) } # rubocop:disable Gitlab/ModuleWithInstanceVariables
13
        end
14
        # rubocop: enable CodeReuse/ActiveRecord
15
16
17
18
19
20
21

        def interval_step
          @interval_step ||= 1.day
        end
      end

      module MonthlyInterval
22
        # rubocop: disable CodeReuse/ActiveRecord
23
24
25
        def grouped_count(query)
          if Gitlab::Database.postgresql?
            query
Maxim Rydkin's avatar
Maxim Rydkin committed
26
              .group("to_char(#{::Ci::Pipeline.table_name}.created_at, '01 Month YYYY')")
27
28
29
30
              .count(:created_at)
              .transform_keys(&:squish)
          else
            query
Maxim Rydkin's avatar
Maxim Rydkin committed
31
              .group("DATE_FORMAT(#{::Ci::Pipeline.table_name}.created_at, '01 %M %Y')")
32
33
34
              .count(:created_at)
          end
        end
35
        # rubocop: enable CodeReuse/ActiveRecord
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

        def interval_step
          @interval_step ||= 1.month
        end
      end

      class Chart
        attr_reader :labels, :total, :success, :project, :pipeline_times

        def initialize(project)
          @labels = []
          @total = []
          @success = []
          @pipeline_times = []
          @project = project

          collect
        end

55
        # rubocop: disable CodeReuse/ActiveRecord
56
        def collect
57
          query = project.all_pipelines
Maxim Rydkin's avatar
Maxim Rydkin committed
58
            .where("? > #{::Ci::Pipeline.table_name}.created_at AND #{::Ci::Pipeline.table_name}.created_at > ?", @to, @from) # rubocop:disable GitlabSecurity/SqlInjection
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

          totals_count  = grouped_count(query)
          success_count = grouped_count(query.success)

          current = @from
          while current < @to
            label = current.strftime(@format)

            @labels  << label
            @total   << (totals_count[label] || 0)
            @success << (success_count[label] || 0)

            current += interval_step
          end
        end
74
        # rubocop: enable CodeReuse/ActiveRecord
75
76
77
78
      end

      class YearChart < Chart
        include MonthlyInterval
79
        attr_reader :to, :from
80
81

        def initialize(*)
82
83
          @to     = Date.today.end_of_month.end_of_day
          @from   = @to.years_ago(1).beginning_of_month.beginning_of_day
84
85
86
87
88
89
90
91
          @format = '%d %B %Y'

          super
        end
      end

      class MonthChart < Chart
        include DailyInterval
92
        attr_reader :to, :from
93
94

        def initialize(*)
95
96
          @to     = Date.today.end_of_day
          @from   = 1.month.ago.beginning_of_day
97
98
99
100
101
102
103
104
          @format = '%d %B'

          super
        end
      end

      class WeekChart < Chart
        include DailyInterval
105
        attr_reader :to, :from
106
107

        def initialize(*)
108
109
          @to     = Date.today.end_of_day
          @from   = 1.week.ago.beginning_of_day
110
111
112
113
114
115
116
117
          @format = '%d %B'

          super
        end
      end

      class PipelineTime < Chart
        def collect
118
          commits = project.all_pipelines.last(30)
119
120
121
122
123
124
125
126
127
128
129

          commits.each do |commit|
            @labels << commit.short_sha
            duration = commit.duration || 0
            @pipeline_times << (duration / 60)
          end
        end
      end
    end
  end
end