Module: Prato::Internal::QueryExecutor

Extended by:
QueryExecutor
Included in:
QueryExecutor
Defined in:
lib/prato/internal/query_executor.rb

Instance Method Summary collapse

Instance Method Details

#execute(scope, spec, raw_params:, paginated: true) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/prato/internal/query_executor.rb', line 8

def execute(scope, spec, raw_params:, paginated: true)
  config = spec.config
  params = resolve_parameters(raw_params, config, spec)

  materialization_fields = spec.validate_and_extract_materialization_fields(params)
  return invalid_input_result(config, paginated) if materialization_fields.nil?

  base_query_state = QueryState.create(scope, materialization_fields)

  filtered_query = Pipeline::Filtering.filter_query(base_query_state, spec, params&.filters)
  sorted_query = Pipeline::Sorting.sort_query(filtered_query, spec, params&.sorts)

  if paginated
    paginated_query = Pipeline::Pagination.paginate_query(sorted_query, config, params&.page, params&.per_page)
    data = Pipeline::Serializer.serialize_query(paginated_query, spec, params&.fields)

    { entries: data, totalCount: total_count(sorted_query) }
  else
    Pipeline::Serializer.serialize_query(sorted_query, spec, params&.fields)
  end
end

#execute_in_batches(scope, spec, raw_params:, batch_size:) ⇒ Object



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
# File 'lib/prato/internal/query_executor.rb', line 30

def execute_in_batches(scope, spec, raw_params:, batch_size:)
  config = spec.config
  params = resolve_parameters(raw_params, config, spec)

  materialization_fields = spec.validate_and_extract_materialization_fields(params)
  if materialization_fields.nil?
    raise ArgumentError if config.on_invalid_input == :raise

    return
  end

  base_query_state = QueryState.create(scope, materialization_fields)
  filtered_query = Pipeline::Filtering.filter_query(base_query_state, spec, params&.filters)
  sorted_query = Pipeline::Sorting.sort_query(filtered_query, spec, params&.sorts)

  is_materialized = !sorted_query.unmaterialized?
  has_sort = !Array(params&.sorts).empty?

  if is_materialized
    sorted_query.dataset.each_slice(batch_size) do |slice|
      batch_state = sorted_query.with_dataset(slice)
      yield Pipeline::Serializer.serialize_query(batch_state, spec, params&.fields)
    end
  elsif has_sort
    offset = 0
    loop do
      relation = sorted_query.dataset.offset(offset).limit(batch_size)
      batch_state = sorted_query.with_dataset(relation)
      serialized = Pipeline::Serializer.serialize_query(batch_state, spec, params&.fields)
      break if serialized.empty?

      yield serialized
      break if serialized.size < batch_size

      offset += batch_size
    end
  else
    sorted_query.dataset.in_batches(of: batch_size) do |relation|
      batch_state = sorted_query.with_dataset(relation)
      yield Pipeline::Serializer.serialize_query(batch_state, spec, params&.fields)
    end
  end
end