summaryrefslogtreecommitdiff
path: root/app/finders/pipelines_finder.rb
blob: a99a889a7e9e43056991c834460c334f0cd9a444 (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
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

  def ids_for_ref(refs)
    pipelines.where(ref: refs).group(:ref).select('max(id)')
  end

  def from_ids(ids)
    pipelines.unscoped.where(id: ids)
  end

  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

  def by_status(items)
    return items unless HasStatus::AVAILABLE_STATUSES.include?(params[:status])

    items.where(status: params[:status])
  end

  def by_ref(items)
    if params[:ref].present?
      items.where(ref: params[:ref])
    else
      items
    end
  end

  def by_sha(items)
    if params[:sha].present?
      items.where(sha: params[:sha])
    else
      items
    end
  end

  def by_name(items)
    if params[:name].present?
      items.joins(:user).where(users: { name: params[:name] })
    else
      items
    end
  end

  def by_username(items)
    if params[:username].present?
      items.joins(:user).where(users: { username: params[:username] })
    else
      items
    end
  end

  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

  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
end