class Sequel::Extensions::Batches::Yielder

Attributes

ds[RW]
finish[RW]
of[RW]
pk[W]
start[RW]

Public Class Methods

new(ds:, pk: nil, of: 1000, start: nil, finish: nil) click to toggle source
# File lib/sequel/extensions/batches/yielder.rb, line 8
def initialize(ds:, pk: nil, of: 1000, start: nil, finish: nil)
  self.ds = ds
  self.pk = pk
  self.of = of
  self.start = start
  self.finish = finish
end

Public Instance Methods

call() { |working_ds| ... } click to toggle source
# File lib/sequel/extensions/batches/yielder.rb, line 16
def call
  base_ds = setup_base_ds or return

  current_instance = nil

  loop do
    working_ds =
      if current_instance
        base_ds.where(generate_conditions(current_instance.to_h, sign: :>))
      else
        base_ds
      end

    working_ds_pk = working_ds.select(*qualified_pk).limit(of)
    current_instance = db.from(working_ds_pk).select(*pk).order(*pk).last or break
    working_ds = working_ds.where(generate_conditions(current_instance.to_h, sign: :<=))

    yield working_ds
  end
end

Private Instance Methods

check_pk(input_pk) click to toggle source
# File lib/sequel/extensions/batches/yielder.rb, line 55
def check_pk(input_pk)
  raise InvalidPKError if input_pk.keys != pk
  input_pk
end
db() click to toggle source
# File lib/sequel/extensions/batches/yielder.rb, line 39
def db
  ds.db
end
generate_conditions(input_pk, sign:) click to toggle source
# File lib/sequel/extensions/batches/yielder.rb, line 60
def generate_conditions(input_pk, sign:)
  raise NullPKError if input_pk.values.any?(&:nil?)
  row_expr = Sequel.function(:row, *input_pk.values)
  Sequel.function(:row, *qualified_pk).public_send(sign, row_expr)
end
pk() click to toggle source
# File lib/sequel/extensions/batches/yielder.rb, line 43
def pk
  @pk ||= begin
    pk = db.schema(ds.first_source).select { |x| x[1][:primary_key] }.map(&:first)
    raise MissingPKError if pk.empty?
    pk
  end
end
qualified_pk() click to toggle source
# File lib/sequel/extensions/batches/yielder.rb, line 51
def qualified_pk
  @qualified_pk ||= pk.map { |x| Sequel[ds.first_source][x] }
end
setup_base_ds() click to toggle source
# File lib/sequel/extensions/batches/yielder.rb, line 66
def setup_base_ds
  base_ds = ds.order(*qualified_pk)
  base_ds = base_ds.where(generate_conditions(check_pk(start), sign: :>=)) if start
  base_ds = base_ds.where(generate_conditions(check_pk(finish), sign: :<=)) if finish

  pk_ds = db.from(base_ds.select(*qualified_pk)).select(*pk).order(*pk)
  actual_start = pk_ds.first
  actual_finish = pk_ds.last

  return unless actual_start && actual_finish

  base_ds = base_ds.where(generate_conditions(actual_start, sign: :>=))
  base_ds = base_ds.where(generate_conditions(actual_finish, sign: :<=))

  base_ds
end