Module: SmartCsvImport::Processor::CsvPreflightAnalyzer

Defined in:
lib/smart_csv_import/processor/csv_preflight_analyzer.rb

Class Method Summary collapse

Class Method Details

.build_duplicate_warning(dup) ⇒ Object



19
20
21
22
23
24
25
# File 'lib/smart_csv_import/processor/csv_preflight_analyzer.rb', line 19

def build_duplicate_warning(dup)
  RowWarning.new(
    row: 0,
    message: "Duplicate column '#{dup[:original]}' — occurrence renamed to '#{dup[:renamed_to]}'",
    type: :duplicate_header
  )
end

.count_nil_matches(file_path:, nil_values:) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/smart_csv_import/processor/csv_preflight_analyzer.rb', line 34

def count_nil_matches(file_path:, nil_values:)
  return 0 if nil_values.nil? || (nil_values.respond_to?(:empty?) && nil_values.empty?)

  count = 0
  begin
    each_data_row(file_path) { |row| count += NilCellCounter.count_row(row, nil_values) }
  rescue CSV::MalformedCSVError
    # Stop the scan and return the partial count — SmarterCSV surfaces the parse error downstream.
  end
  count
rescue Errno::ENOENT, Errno::EACCES => e
  raise SmartCsvImport::Error, "Failed to read CSV for nil-value scan in #{File.basename(file_path)}: #{e.message}"
end

.duplicate_header_warnings(file_path:) ⇒ Object



10
11
12
13
14
15
16
17
# File 'lib/smart_csv_import/processor/csv_preflight_analyzer.rb', line 10

def duplicate_header_warnings(file_path:)
  headers = read_headers(file_path)
  return [] if headers.nil?

  find_duplicates(headers).map { |dup| build_duplicate_warning(dup) }
rescue StandardError
  []
end

.each_data_row(file_path) ⇒ Object



62
63
64
65
66
67
68
69
70
71
# File 'lib/smart_csv_import/processor/csv_preflight_analyzer.rb', line 62

def each_data_row(file_path)
  first_row = true
  CSV.foreach(file_path, encoding: 'bom|utf-8:utf-8', invalid: :replace, undef: :replace) do |row|
    if first_row
      first_row = false
      next
    end
    yield row
  end
end

.find_duplicates(headers) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/smart_csv_import/processor/csv_preflight_analyzer.rb', line 48

def find_duplicates(headers)
  seen = {}
  headers.each_with_object([]) do |header, duplicates|
    next unless header

    if seen[header]
      seen[header] += 1
      duplicates << { original: header, renamed_to: "#{header}_#{seen[header]}" }
    else
      seen[header] = 1
    end
  end
end

.read_headers(file_path) ⇒ Object



27
28
29
30
31
32
# File 'lib/smart_csv_import/processor/csv_preflight_analyzer.rb', line 27

def read_headers(file_path)
  first_line = File.open(file_path, 'r:bom|utf-8:utf-8', invalid: :replace, undef: :replace, &:gets)
  return nil unless first_line

  CSV.parse_line(first_line)&.map { |h| h&.strip }
end