class ActiveRecordCopy::CopyFromClient::CopyHandler

Public Class Methods

new(columns:, model_class:, table_name:) click to toggle source
# File lib/activerecord-copy.rb, line 19
def initialize(columns:, model_class:, table_name:)
  @columns      = columns
  @model_class  = model_class
  @connection   = model_class.connection.raw_connection
  @table_name   = table_name
  @column_types = columns.map do |c|
    column = model_class.columns_hash[c.to_s]
    raise format('Could not find column %s on %s', c, model_class.table_name) if column.nil?

    if column.type == :integer
      if column.limit == 8
        :bigint
      elsif column.limit == 2
        :smallint
      else
        :integer
      end
    else
      column.type
    end
  end

  reset
end

Public Instance Methods

<<(row) click to toggle source
# File lib/activerecord-copy.rb, line 44
def <<(row)
  @encoder.add row
end
close() click to toggle source
# File lib/activerecord-copy.rb, line 48
def close
  run_copy
end

Private Instance Methods

reset() click to toggle source
# File lib/activerecord-copy.rb, line 72
def reset
  @encoder = ActiveRecordCopy::EncodeForCopy.new column_types: @column_types
  @row_count = 0
end
run_copy() click to toggle source
# File lib/activerecord-copy.rb, line 54
def run_copy
  io = @encoder.get_io

  @connection.copy_data %{COPY #{@table_name}("#{@columns.join('","')}") FROM STDIN BINARY} do
    begin
      while chunk = io.readpartial(10_240) # rubocop:disable Lint/AssignmentInCondition
        @connection.put_copy_data chunk
      end
    rescue EOFError # rubocop:disable Lint/HandleExceptions
    end
  end

  @encoder.remove
  reset

  nil
end