Class: CsvRowModel::Import::Csv
- Inherits:
-
Object
- Object
- CsvRowModel::Import::Csv
- Includes:
- ActiveModel::Validations
- Defined in:
- lib/csv_row_model/import/csv.rb
Overview
Abstraction of Ruby's CSV library. Keeps current row and index, skips empty rows, handles errors.
Instance Attribute Summary collapse
-
#current_row ⇒ Array?
readonly
The current row, or nil at the beginning or end of file.
-
#file_path ⇒ String
readonly
The file path of the CSV.
-
#index ⇒ Integer?
readonly
Return
-1at start of file,0 to infinityis index of row_model,nilis end of file (row is alsonil). -
#skipped_rows ⇒ Hash{Integer => Symbol}
readonly
Hash of skipped rows from last change in position,
index => :reason.
Instance Method Summary collapse
- #_read_row(skipped_rows = {}, index = @index, ruby_csv = @ruby_csv) ⇒ Object protected
- #_ruby_csv ⇒ Object protected
-
#end_of_file? ⇒ Boolean
True, if the current position is at the end of the file.
-
#header ⇒ Array?
Returns the header without changing the position of the CSV.
- #increment_index(current_row) ⇒ Object protected
-
#initialize(file_path) ⇒ Csv
constructor
A new instance of Csv.
-
#next_row ⇒ Array?
Returns the next row without changing the position of the CSV.
-
#read_row ⇒ Array?
Returns the next row, while changing the position of the CSV.
-
#reset ⇒ Object
Resets the file to the start of file.
- #set_end_of_file ⇒ Object protected
- #size ⇒ Integer
-
#skip_header ⇒ Boolean, Array
If the current position is at the header, skip it and return it.
-
#start_of_file? ⇒ Boolean
True, if the current position is at the start of the file.
Constructor Details
#initialize(file_path) ⇒ Csv
Returns a new instance of Csv.
21 22 23 24 |
# File 'lib/csv_row_model/import/csv.rb', line 21 def initialize(file_path) @file_path = file_path reset end |
Instance Attribute Details
#current_row ⇒ Array? (readonly)
Returns the current row, or nil at the beginning or end of file.
10 11 12 |
# File 'lib/csv_row_model/import/csv.rb', line 10 def current_row @current_row end |
#file_path ⇒ String (readonly)
Returns the file path of the CSV.
6 7 8 |
# File 'lib/csv_row_model/import/csv.rb', line 6 def file_path @file_path end |
#index ⇒ Integer? (readonly)
Return -1 at start of file, 0 to infinity is index of row_model, nil is end of file (row is also nil)
8 9 10 |
# File 'lib/csv_row_model/import/csv.rb', line 8 def index @index end |
#skipped_rows ⇒ Hash{Integer => Symbol} (readonly)
Returns hash of skipped rows from last change in position, index => :reason.
12 13 14 |
# File 'lib/csv_row_model/import/csv.rb', line 12 def skipped_rows @skipped_rows end |
Instance Method Details
#_read_row(skipped_rows = {}, index = @index, ruby_csv = @ruby_csv) ⇒ Object (protected)
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/csv_row_model/import/csv.rb', line 102 def _read_row(skipped_rows={}, index=@index, ruby_csv=@ruby_csv) return unless valid? row = ruby_csv.readline raise "empty?" if row.try(:empty?) index += 1 if index yield row if block_given? row rescue Exception => e index += 1 if index yield [] if block_given? # thanks to the ruby CSV library, quotes can still escape to the next line reason = case e. when "empty?"; :empty when /Illegal quoting/i; :illegal_quote when /Unclosed quoted/i; :unclosed_quote end skipped_rows.merge!(index => reason) retry end |
#_ruby_csv ⇒ Object (protected)
98 99 100 |
# File 'lib/csv_row_model/import/csv.rb', line 98 def _ruby_csv CSV.open(file_path) end |
#end_of_file? ⇒ Boolean
Returns true, if the current position is at the end of the file.
66 67 68 |
# File 'lib/csv_row_model/import/csv.rb', line 66 def end_of_file? index.nil? end |
#header ⇒ Array?
Returns the header without changing the position of the CSV
40 41 42 43 44 45 46 47 48 |
# File 'lib/csv_row_model/import/csv.rb', line 40 def header return unless valid? return @header if @header ruby_csv = _ruby_csv @header = _read_row({}, 0, ruby_csv) ruby_csv.close @header end |
#increment_index(current_row) ⇒ Object (protected)
128 129 130 |
# File 'lib/csv_row_model/import/csv.rb', line 128 def increment_index(current_row) current_row.nil? ? set_end_of_file : @index += 1 end |
#next_row ⇒ Array?
Returns the next row without changing the position of the CSV
72 73 74 75 |
# File 'lib/csv_row_model/import/csv.rb', line 72 def next_row @next_skipped_rows = {} @next_row ||= _read_row(@next_skipped_rows) end |
#read_row ⇒ Array?
Returns the next row, while changing the position of the CSV
79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/csv_row_model/import/csv.rb', line 79 def read_row if @next_row @current_row, @skipped_rows = @next_row, @next_skipped_rows @next_row = nil increment_index(@current_row) else @skipped_rows = {} @current_row = _read_row(@skipped_rows) do |row| increment_index(row) end end current_row end |
#reset ⇒ Object
Resets the file to the start of file
51 52 53 54 55 56 57 58 |
# File 'lib/csv_row_model/import/csv.rb', line 51 def reset return unless valid? @index = -1 @current_row = @next_row = @skipped_rows = @next_skipped_rows = nil @ruby_csv = _ruby_csv true end |
#set_end_of_file ⇒ Object (protected)
94 95 96 |
# File 'lib/csv_row_model/import/csv.rb', line 94 def set_end_of_file @current_row = @index = nil end |
#size ⇒ Integer
28 29 30 |
# File 'lib/csv_row_model/import/csv.rb', line 28 def size @size ||= `wc -l #{file_path}`.split[0].to_i + 1 end |
#skip_header ⇒ Boolean, Array
If the current position is at the header, skip it and return it. Otherwise, only return false.
34 35 36 |
# File 'lib/csv_row_model/import/csv.rb', line 34 def skip_header start_of_file? ? (@header = read_row) : false end |
#start_of_file? ⇒ Boolean
Returns true, if the current position is at the start of the file.
61 62 63 |
# File 'lib/csv_row_model/import/csv.rb', line 61 def start_of_file? index == -1 end |