class CSVFile

That class helps to work with csv in pry or irb with some useful methods already defined. (Gem created just as a part of practice) PS: Stupid idea? if you think about it seriously more than 10 seconds? because almost everything work via CSV gem as you can see in require section

Attributes

data[RW]
file_col_sep[R]
file_extension[R]
file_headers[RW]
file_name[RW]
output[RW]

Public Class Methods

new(file_name: nil, file_extension: DefaultConstants::EXTENSION, convert: false, output: DefaultConstants::FILE_PATTERN) click to toggle source

initializer method for CSVFile

# File lib/csvn.rb, line 13
def initialize(file_name: nil, file_extension: DefaultConstants::EXTENSION, convert: false, output: DefaultConstants::FILE_PATTERN)
  @file_name = file_name                ### source file name (full path should be provided)
  @file_extension = file_extension      ### file extension
  @data = []                            ### file rows data
  @smart_convert = convert              ### convert readed data in array of hashes with file headers keys - false by default
  @file_headers = nil                   ### file headers array
  @read_flag = false                    ### service flag
  @output = output            ### write file name with extension
end

Public Instance Methods

delete(opts={}) click to toggle source
# File lib/csvn.rb, line 135
def delete(opts={})
  # opts - condition hash where :key is column value and :value - row value to chech for eql? with what you needed
end
info() click to toggle source

Show some useful info about working file

# File lib/csvn.rb, line 24
def info
  @encoding = find_enoding
  puts "INFO:"
  print 'File name         '; print "#{@file_name}\n".colorize(:green)
  print 'File headers      '; print "#{@file_headers}\n".colorize(:green)
  print 'File rows number  '; print "#{@data.size}\n".colorize(:green)
  print 'File encoding     '; print "#{@encoding}\n".colorize(:green)

  ## temp decision
  if @output_file_name
    print 'Output File   '; print "#{@output_file_name || 'nil'}\n".colorize(:green)
  end
end
max(opts={}) click to toggle source
# File lib/csvn.rb, line 96
def max(opts={})
  return ":by key must be provided for that method." unless opts[:by]

  raise_exceptions(__method__)

  value_statement = opts[:apply] ? "data_h[opts[:by]].#{opts[:apply]}" : "data_h[opts[:by]]"
  @data.max_by do |data_h|
    begin
      eval(value_statement)
    rescue NoMethodError => err
      puts err.message
      break
    end
  end
end
mean(opts={}) click to toggle source
# File lib/csvn.rb, line 127
def mean(opts={})
  return ":by key must be provided for that method." unless opts[:by]
  raise_exceptions(__method__)

  mean_statement = opts[:apply] ? "data_h[opts[:by]].#{opts[:apply]}" : "data_h[opts[:by]]"
  @data.map { |data_h| eval(mean_statement) }.sum.to_f / @data.size
end
min(opts={}) click to toggle source
# File lib/csvn.rb, line 112
def min(opts={})
  return ":by key must be provided for that method." unless opts[:by]
  raise_exceptions(__method__)

  value_statement = opts[:apply] ? "data_h[opts[:by]].#{opts[:apply]}" : "data_h[opts[:by]]"
  @data.min_by do |data_h|
    begin
      eval(value_statement)
    rescue NoMethodError => err
      puts err.message
      break
    end
  end
end
read() click to toggle source

Read dta from file Param :only can define limit of readed lines from file - not implemented yet

# File lib/csvn.rb, line 40
def read
  return if @read_flag

  process_reading
end
select(opts = {}) click to toggle source

Only for string row values will be improved to be able to handle more complex selecting like SQL does —-> multiple select

# File lib/csvn.rb, line 61
def select(opts = {})
  return @data.select { |row| row[opts[:where]] =~ /#{opts[:like]}/ } if opts[:like]
  return @data.select { |row| row[opts[:where]] !~ /#{opts[:not_like]}/ } if opts[:not_like]

  @data.select { |row| row[opts[:where]] == opts[:equals] }
end
smart_convert!() click to toggle source

Convert readed data to hash with headers keys Need to prevent reading only in one format and to give opportunity to choose data presentation

# File lib/csvn.rb, line 70
def smart_convert!
  if @file_headers.any?
    @data = @data.map { |d_arr| @file_headers.each_with_object({}).with_index { |(h_name, h_hash), ind| h_hash[h_name] = d_arr[ind] } }
    @smart_convert = true
  end
end
sort(opts={}) click to toggle source
# File lib/csvn.rb, line 77
  def sort(opts={})
    return nil unless @data

    raise_exceptions(__method__)
    compare_statement = opts[:apply] ? "data_h[opts[:by]].#{opts[:apply]}" : "data_h[opts[:by]]"

    sort_statement = <<-SORT_STATEMENT
      @data.sort_by do |data_h|
        begin
          eval(compare_statement)
        rescue NoMethodError => err
          puts err.message
          break
        end
      end#{opts[:desc] ? ".reverse" : ""}
    SORT_STATEMENT
    eval(sort_statement)
  end
write(data_to_write:, headers: [], encoding: DefaultConstants::ENCODING) click to toggle source

Write data in file (named by pattern - may be found in DefaultConstants::FILE_PATTERN) Will write data every time it calles to ensure that all current data writed in file - may occurs duplicate if used more than once If data_to_write - is array of hashes - will use first hash keys as headers, else - headers that provided by :header key in method call

# File lib/csvn.rb, line 49
def write(data_to_write:, headers: [], encoding: DefaultConstants::ENCODING)
  data_prepared, headers_prepared = prepare_data_for_writing(data_to_write, headers)
  begin
    process_writing(data_prepared, headers_prepared, encoding)
    puts "Writed in #{@output}".colorize(:cyan)
  rescue StandardError => e2
    e2.message
  end
end

Private Instance Methods

find_enoding() click to toggle source

find out file encoding

# File lib/csvn.rb, line 162
def find_enoding
  scmdlog = `file -I #{@file_name}`.strip
  scmdlog[/charset=(.+?)$/, 1]
end
open_and_read_file() click to toggle source
# File lib/csvn.rb, line 191
def open_and_read_file
  raise "No file name specified for reading data. Set file name with #{self.class}.file_name = <value>" unless @file_name
  DefaultConstants::COL_SEPS.each do |separator|
    begin
      @file_col_sep = separator
      @file_headers = nil
      CSV.foreach(@file_name, col_sep: separator).with_index do |row_csv, row_index|
        if row_index.zero?
          @file_headers = row_csv
          next
        end
        @data << row_csv
      end

      break
    rescue CSV::MalformedCSVError => e
      @file_headers = nil
      next
    rescue StandardError => e2
      @file_headers = nil
      next
    end
  end
end
open_and_write_data(data, headers, encoding) click to toggle source
# File lib/csvn.rb, line 216
def open_and_write_data(data, headers, encoding)
  CSV.open(@output, 'w+', col_sep: DefaultConstants::COL_SEP, write_headers: true, headers: headers, encoding: encoding) do |csv_element|
    data.each do |data_sample|
      csv_element << data_sample
    end
  end
end
prepare_data_for_writing(data_to_write, headers) click to toggle source

service methods that not need to be opened for usage outside if need more - contact please me or contribute yourself by merge request

# File lib/csvn.rb, line 144
def prepare_data_for_writing(data_to_write, headers)
  if data_to_write.first.class.to_s.downcase =~ /hash/
    prepared_headers = data_to_write.first.keys.map(&:to_s)
    prepared_data_to_write = data_to_write.map { |data_h| data_h.values }
    return prepared_data_to_write, prepared_headers
  elsif data_to_write.first.class.to_s.downcase =~ /array/
    raise "No headers provided for writing" if !headers or headers.empty?

    return data_to_write, headers
  end
end
process_reading() click to toggle source

read data from file

# File lib/csvn.rb, line 168
def process_reading
  begin
    open_and_read_file
    @read_flag = true
    puts 'Success. Check instance fields'.colorize(:green)
  rescue StandardError => e
    puts e.message
  end
end
process_writing(data_to_write, headers, encoding) click to toggle source

write data into file (upstream in <class>#write method)

# File lib/csvn.rb, line 179
def process_writing(data_to_write, headers, encoding)
  begin
    open_and_write_data(data_to_write, headers, encoding)
    @write_flag = true
    puts 'Success. Check file with new data'
  rescue StandardError => e
    puts e.message
  rescue CSV::MalformedCSVError => e2
    puts e2.message
  end
end
raise_exceptions(called_method) click to toggle source
# File lib/csvn.rb, line 156
def raise_exceptions(called_method)
  raise "Need to <CSVFile instance>.smart_convert! your file data first to proceed #{called_method}." unless @smart_convert
  raise "No data readed. Check these please before calling #{called_method}" unless @data
end