Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/services/import_csv/base_service.rb')
-rw-r--r--app/services/import_csv/base_service.rb40
1 files changed, 34 insertions, 6 deletions
diff --git a/app/services/import_csv/base_service.rb b/app/services/import_csv/base_service.rb
index feb76425fb4..70834b8a85a 100644
--- a/app/services/import_csv/base_service.rb
+++ b/app/services/import_csv/base_service.rb
@@ -2,6 +2,8 @@
module ImportCsv
class BaseService
+ include Gitlab::Utils::StrongMemoize
+
def initialize(user, project, csv_io)
@user = user
@project = project
@@ -9,6 +11,8 @@ module ImportCsv
@results = { success: 0, error_lines: [], parse_error: false }
end
+ PreprocessError = Class.new(StandardError)
+
def execute
process_csv
email_results_to_user
@@ -36,7 +40,23 @@ module ImportCsv
raise NotImplementedError
end
+ def validate_structure!
+ header_line = csv_data.lines.first
+ raise CSV::MalformedCSVError.new('File is empty, no headers found', 1) if header_line.blank?
+
+ validate_headers_presence!(header_line)
+ detect_col_sep
+ end
+
+ def preprocess!
+ # any logic can be added in subclasses if needed
+ # hence just a no-op rather than NotImplementedError
+ end
+
def process_csv
+ validate_structure!
+ preprocess!
+
with_csv_lines.each do |row, line_no|
attributes = attributes_for(row)
@@ -46,23 +66,30 @@ module ImportCsv
results[:error_lines].push(line_no)
end
end
- rescue ArgumentError, CSV::MalformedCSVError
+ rescue ArgumentError, CSV::MalformedCSVError => e
results[:parse_error] = true
+ results[:error_lines].push(e.line_number) if e.respond_to?(:line_number)
+ rescue PreprocessError
+ results[:parse_error] = false
end
def with_csv_lines
- csv_data = @csv_io.open(&:read).force_encoding(Encoding::UTF_8)
- validate_headers_presence!(csv_data.lines.first)
-
CSV.new(
csv_data,
- col_sep: detect_col_sep(csv_data.lines.first),
+ col_sep: detect_col_sep,
headers: true,
header_converters: :symbol
).each.with_index(2)
end
- def detect_col_sep(header)
+ def csv_data
+ @csv_io.open(&:read).force_encoding(Encoding::UTF_8)
+ end
+ strong_memoize_attr :csv_data
+
+ def detect_col_sep
+ header = csv_data.lines.first
+
if header.include?(",")
","
elsif header.include?(";")
@@ -73,6 +100,7 @@ module ImportCsv
raise CSV::MalformedCSVError.new('Invalid CSV format', 1)
end
end
+ strong_memoize_attr :detect_col_sep
def create_object(attributes)
# NOTE: CSV imports are performed by workers, so we do not have a request context in order