-
Notifications
You must be signed in to change notification settings - Fork 16
/
base.rb
100 lines (77 loc) · 2.39 KB
/
base.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
require "csv"
module CsvImporter
class Base
include CsvImporter::Config
attr_reader :errors, :rows, :deleted_row_count, :skipped_row_count
def initialize(file)
@errors = []
@rows = parse_csv_file(file)
@deleted_row_count = 0
@skipped_row_count = 0
check_headers if rows && with_headers?
end
def run
@deleted_row_count = delete_all_scope.delete_all unless append_only
rows.each_slice(batch_size).with_index(1) do |batch_rows, i|
Rails.logger.info "Processing #{target_data_model.to_s.titleize} batch #{i}"
record_hashes = batch_rows.map do |row|
if empty_row?(row) || valid_skip_row_conditions?(row)
@skipped_row_count += 1
next
end
convert_row_to_hash(row)
end.compact
target_data_model.insert_all(record_hashes) unless record_hashes.empty?
end
sync_analytics
end
def rows_with_data_count
rows.count - skipped_row_count
end
private
def sync_analytics
AnalyticsImporter.import(target_data_model)
end
def empty_row?(row)
case row
when Array
row.all? { |cell| cell.blank? }
else
row.all? { |_, v| v.blank? }
end
end
def delete_all_scope
target_data_model
end
def with_headers?
parse_headers && mandatory_headers&.is_a?(Array) && mandatory_headers.any?
end
def check_headers
missing_headers = mandatory_headers - rows.headers
if missing_headers.any?
errors.append("The selected file is missing some expected columns: #{missing_headers.join(", ")}")
end
end
def parse_csv_file(file)
if file.nil?
errors.append("Select a file")
nil
else
string = File.open(file.path, "r", encoding: "BOM|UTF-8").read.scrub
CSV.parse(string, headers: parse_headers)
end
rescue CSV::MalformedCSVError
errors.append("The selected file must be a CSV")
nil
end
def valid_skip_row_conditions?(row)
return false unless skip_row_if_method || skip_row_if_lambda
return method(skip_row_if_method).call(row) if skip_row_if_method
skip_row_if_lambda&.call(row)
end
def convert_row_to_hash(row)
return method(transform_rows_with_method).call(row) if transform_rows_with_method
transform_rows_with_lambda&.call(row)
end
end
end