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
|
# frozen_string_literal: true
module Sidekiq
module Job
module Iterable
# @api private
class ActiveRecordEnumerator
def initialize(relation, cursor: nil, **options)
@relation = relation
@cursor = cursor
@options = options
end
def records
Enumerator.new(-> { @relation.count }) do |yielder|
@relation.find_each(**@options, start: @cursor) do |record|
yielder.yield(record, record.id)
end
end
end
def batches
Enumerator.new(-> { @relation.count }) do |yielder|
@relation.find_in_batches(**@options, start: @cursor) do |batch|
yielder.yield(batch, batch.first.id)
end
end
end
def relations
Enumerator.new(-> { relations_size }) do |yielder|
# Convenience to use :batch_size for all the
# ActiveRecord batching methods.
options = @options.dup
options[:of] ||= options.delete(:batch_size)
@relation.in_batches(**options, start: @cursor) do |relation|
first_record = relation.first
yielder.yield(relation, first_record.id)
end
end
end
private
def relations_size
batch_size = @options[:batch_size] || 1000
(@relation.count + batch_size - 1) / batch_size # ceiling division
end
end
end
end
end
|