summaryrefslogtreecommitdiff
path: root/app/finders/pipelines_finder.rb
blob: 35d0e1acce5424d363d8c723f510bdc5edfded44 (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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# frozen_string_literal: true

class PipelinesFinder
  attr_reader :project, :pipelines, :params, :current_user

  ALLOWED_INDEXED_COLUMNS = %w[id status ref user_id].freeze

  def initialize(project, current_user, params = {})
    @project = project
    @current_user = current_user
    @pipelines = project.pipelines
    @params = params
  end

  def execute
    unless Ability.allowed?(current_user, :read_pipeline, project)
      return Ci::Pipeline.none
    end

    items = pipelines
    items = by_scope(items)
    items = by_status(items)
    items = by_ref(items)
    items = by_sha(items)
    items = by_name(items)
    items = by_username(items)
    items = by_yaml_errors(items)
    sort_items(items)
  end

  private

  # rubocop: disable CodeReuse/ActiveRecord
  def ids_for_ref(refs)
    pipelines.where(ref: refs).group(:ref).select('max(id)')
  end
  # rubocop: enable CodeReuse/ActiveRecord

  # rubocop: disable CodeReuse/ActiveRecord
  def from_ids(ids)
    pipelines.unscoped.where(id: ids)
  end
  # rubocop: enable CodeReuse/ActiveRecord

  def branches
    project.repository.branch_names
  end

  def tags
    project.repository.tag_names
  end

  def by_scope(items)
    case params[:scope]
    when 'running'
      items.running
    when 'pending'
      items.pending
    when 'finished'
      items.finished
    when 'branches'
      from_ids(ids_for_ref(branches))
    when 'tags'
      from_ids(ids_for_ref(tags))
    else
      items
    end
  end

  # rubocop: disable CodeReuse/ActiveRecord
  def by_status(items)
    return items unless HasStatus::AVAILABLE_STATUSES.include?(params[:status])

    items.where(status: params[:status])
  end
  # rubocop: enable CodeReuse/ActiveRecord

  # rubocop: disable CodeReuse/ActiveRecord
  def by_ref(items)
    if params[:ref].present?
      items.where(ref: params[:ref])
    else
      items
    end
  end
  # rubocop: enable CodeReuse/ActiveRecord

  # rubocop: disable CodeReuse/ActiveRecord
  def by_sha(items)
    if params[:sha].present?
      items.where(sha: params[:sha])
    else
      items
    end
  end
  # rubocop: enable CodeReuse/ActiveRecord

  # rubocop: disable CodeReuse/ActiveRecord
  def by_name(items)
    if params[:name].present?
      items.joins(:user).where(users: { name: params[:name] })
    else
      items
    end
  end
  # rubocop: enable CodeReuse/ActiveRecord

  # rubocop: disable CodeReuse/ActiveRecord
  def by_username(items)
    if params[:username].present?
      items.joins(:user).where(users: { username: params[:username] })
    else
      items
    end
  end
  # rubocop: enable CodeReuse/ActiveRecord

  # rubocop: disable CodeReuse/ActiveRecord
  def by_yaml_errors(items)
    case Gitlab::Utils.to_boolean(params[:yaml_errors])
    when true
      items.where("yaml_errors IS NOT NULL")
    when false
      items.where("yaml_errors IS NULL")
    else
      items
    end
  end
  # rubocop: enable CodeReuse/ActiveRecord

  # rubocop: disable CodeReuse/ActiveRecord
  def sort_items(items)
    order_by = if ALLOWED_INDEXED_COLUMNS.include?(params[:order_by])
                 params[:order_by]
               else
                 :id
               end

    sort = if params[:sort] =~ /\A(ASC|DESC)\z/i
             params[:sort]
           else
             :desc
           end

    items.order(order_by => sort)
  end
  # rubocop: enable CodeReuse/ActiveRecord
end