Sha256: 966977a68edcc7f29eb01e18e10237f8c0e83b27edf0362bc38430d2ed51e1e5

Contents?: true

Size: 1.7 KB

Versions: 3

Compression:

Stored size: 1.7 KB

Contents

# frozen_string_literal: true

require_relative "./active_record_cursor"
module JobIteration
  # Builds Enumerator based on ActiveRecord Relation. Supports enumerating on rows and batches.
  # @see EnumeratorBuilder
  class ActiveRecordEnumerator
    SQL_DATETIME_WITH_NSEC = "%Y-%m-%d %H:%M:%S.%N"

    def initialize(relation, columns: nil, batch_size: 100, cursor: nil)
      @relation = relation
      @batch_size = batch_size
      @columns = Array(columns || "#{relation.table_name}.#{relation.primary_key}")
      @cursor = cursor
    end

    def records
      Enumerator.new(method(:size)) do |yielder|
        batches.each do |batch, _|
          batch.each do |record|
            yielder.yield(record, cursor_value(record))
          end
        end
      end
    end

    def batches
      cursor = finder_cursor
      Enumerator.new(method(:size)) do |yielder|
        while (records = cursor.next_batch(@batch_size))
          yielder.yield(records, cursor_value(records.last)) if records.any?
        end
      end
    end

    def size
      @relation.count(:all)
    end

    private

    def cursor_value(record)
      positions = @columns.map do |column|
        attribute_name = column.to_s.split(".").last
        column_value(record, attribute_name)
      end
      return positions.first if positions.size == 1
      positions
    end

    def finder_cursor
      JobIteration::ActiveRecordCursor.new(@relation, @columns, @cursor)
    end

    def column_value(record, attribute)
      value = record.read_attribute(attribute.to_sym)
      case record.class.columns_hash.fetch(attribute).type
      when :datetime
        value.strftime(SQL_DATETIME_WITH_NSEC)
      else
        value
      end
    end
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
job-iteration-1.3.5 lib/job-iteration/active_record_enumerator.rb
job-iteration-1.3.4 lib/job-iteration/active_record_enumerator.rb
job-iteration-1.3.3 lib/job-iteration/active_record_enumerator.rb