Class: BulkProcessor::CSVProcessor

Inherits:
Object
  • Object
show all
Defined in:
lib/bulk_processor/csv_processor.rb,
lib/bulk_processor/csv_processor/result.rb,
lib/bulk_processor/csv_processor/no_op_handler.rb,
lib/bulk_processor/csv_processor/row_processor.rb,
lib/bulk_processor/csv_processor/no_op_post_processor.rb

Overview

An abstract implmentation of the CSVProcessor role. Provides

* A default implementation of `.optional_columns`, returning []
* An initializer that assigns the arguments as instance attributes
* An implementation of #start to cover a common use case

The common use case cover by this class’ implementation of ‘#start` is

1. Iteratively process each row
2. Accumulate the results (did the processing succeed? what were the error
   messages?)
3. Send the results to an instance of the Handler role.

This class adds 2 required class methods that can be overridden in any subclass

* row_processor_class - (required) Returns the class that implements the
  RowProcessor role to process rows of the CSV
* handler_class - (optional) Returns the class that implements the Handler
  role,  which handles results from the completion (or failure) of
  processing the entire CSV.

The ‘required_columns` method must still be implemented in a subclass

Defined Under Namespace

Classes: NoOpHandler, NoOpPostProcessor, Result, RowProcessor

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(csv, payload: {}) ⇒ CSVProcessor

Returns a new instance of CSVProcessor.



68
69
70
71
72
# File 'lib/bulk_processor/csv_processor.rb', line 68

def initialize(csv, payload: {})
  @payload = payload
  @row_processors = csv.map.with_index(&method(:row_processor))
  @results = []
end

Class Method Details

.handler_classHandler

Returns a class that implements the Handler role.

Returns:

  • (Handler)

    a class that implements the Handler role



45
46
47
# File 'lib/bulk_processor/csv_processor.rb', line 45

def self.handler_class
  NoOpHandler
end

.optional_columnsArray<String>

Returns column headers that may be present. If a column header is present that is not in ‘required_columns’ or ‘optional_columns’, the file will be considered invalid and no rows will be processed.

Returns:

  • (Array<String>)

    column headers that may be present. If a column header is present that is not in ‘required_columns’ or ‘optional_columns’, the file will be considered invalid and no rows will be processed.



64
65
66
# File 'lib/bulk_processor/csv_processor.rb', line 64

def self.optional_columns
  []
end

.post_processor_classPostProcessor

Returns a class that implements the PostProcessor role.

Returns:

  • (PostProcessor)

    a class that implements the PostProcessor role



50
51
52
# File 'lib/bulk_processor/csv_processor.rb', line 50

def self.post_processor_class
  NoOpPostProcessor
end

.required_columnsArray<String>

Returns column headers that must be present.

Returns:

  • (Array<String>)

    column headers that must be present

Raises:

  • (NotImplementedError)


55
56
57
58
# File 'lib/bulk_processor/csv_processor.rb', line 55

def self.required_columns
  raise NotImplementedError,
        "#{self.class.name} must implement #{__method__}"
end

.row_processor_classRowProcessor

Returns a class that implements the RowProcessor interface.

Returns:

  • (RowProcessor)

    a class that implements the RowProcessor interface

Raises:

  • (NotImplementedError)


39
40
41
42
# File 'lib/bulk_processor/csv_processor.rb', line 39

def self.row_processor_class
  raise NotImplementedError,
        "#{self.class.name} must implement #{__method__}"
end

Instance Method Details

#startObject

Iteratively process each row, accumulate the results, and pass those off to the handler. If an unrescued error is raised for any row, processing will halt for all remaining rows and the ‘#fail!` will be invoked on the handler.



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/bulk_processor/csv_processor.rb', line 78

def start
  row_processors.each do |processor|
    processor.process!
    results << processor.result
  end
  post_processes
  handler.complete!
rescue Exception => exception
  handler.fail!(exception)

  # Swallow any StandardError, since we are already reporting it to the
  # user. However, we must re-raise Exceptions, such as SIGTERMs since they
  # need to be handled at a level above this gem.
  raise unless exception.is_a?(StandardError)
end