Welcome to mirror list, hosted at ThFree Co, Russian Federation.

record_loader_strategy.rb « strategies « in_operator_optimization « keyset « pagination « gitlab « lib - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 4f79a3593f44d7b27b5ae7ae518cda76942b1454 (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
# frozen_string_literal: true

module Gitlab
  module Pagination
    module Keyset
      module InOperatorOptimization
        module Strategies
          class RecordLoaderStrategy
            RECORDS_COLUMN = 'records'

            def initialize(finder_query, model, order_by_columns)
              verify_order_by_attributes_on_model!(model, order_by_columns)

              @finder_query = finder_query
              @order_by_columns = order_by_columns
              @table_name = model.table_name
            end

            def initializer_columns
              ["NULL::#{table_name} AS #{RECORDS_COLUMN}"]
            end

            def columns
              query = finder_query
                .call(*order_by_columns.array_lookup_expressions_by_position(QueryBuilder::RECURSIVE_CTE_NAME))
                .select("#{table_name}")
                .limit(1)

              ["(#{query.to_sql})"]
            end

            def final_projections
              ["(#{RECORDS_COLUMN}).*"]
            end

            private

            attr_reader :finder_query, :order_by_columns, :table_name

            def verify_order_by_attributes_on_model!(model, order_by_columns)
              order_by_columns.map(&:column).each do |column|
                next if model.columns_hash[column.attribute_name.to_s]

                text = <<~TEXT
                    The "RecordLoaderStrategy" does not support the following ORDER BY column because
                    it's not available on the \"#{model.table_name}\" table: #{column.attribute_name}

                    Omit the "finder_query" parameter to use the "OrderValuesLoaderStrategy".
                TEXT
                raise text
              end
            end
          end
        end
      end
    end
  end
end