summaryrefslogtreecommitdiff
path: root/lib/gitlab/usage/metrics/names_suggestions/relation_parsers/joins.rb
blob: d52e4903f3c0fa5e65207c594189563f5d41c3dd (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
# frozen_string_literal: true

module Gitlab
  module Usage
    module Metrics
      module NamesSuggestions
        module RelationParsers
          class Joins < ::Arel::Visitors::PostgreSQL
            def accept(object)
              object.source.right.map do |join|
                visit(join, collector)
              end
            end

            private

            # rubocop:disable Naming/MethodName
            def visit_Arel_Nodes_StringJoin(object, collector)
              result = visit(object.left, collector)
              source, constraints = result.value.split('ON')
              {
                source: source.split('JOIN').last&.strip,
                constraints: constraints&.strip
              }.compact
            end

            def visit_Arel_Nodes_FullOuterJoin(object, _)
              parse_join(object)
            end

            def visit_Arel_Nodes_OuterJoin(object, _)
              parse_join(object)
            end

            def visit_Arel_Nodes_RightOuterJoin(object, _)
              parse_join(object)
            end

            def visit_Arel_Nodes_InnerJoin(object, _)
              {
                source: visit(object.left, collector).value,
                constraints: object.right ? visit(object.right.expr, collector).value : nil
              }.compact
            end
            # rubocop:enable Naming/MethodName

            def parse_join(object)
              {
                source: visit(object.left, collector).value,
                constraints: visit(object.right.expr, collector).value
              }
            end

            def quote(value)
              "#{value}"
            end

            def quote_table_name(name)
              "#{name}"
            end

            def quote_column_name(name)
              "#{name}"
            end

            def collector
              Arel::Collectors::SubstituteBinds.new(@connection, Arel::Collectors::SQLString.new)
            end
          end
        end
      end
    end
  end
end