Class: ExcelImport::ExcelLoader
- Inherits:
-
DataShift::LoaderBase
- Object
- DataShift::LoaderBase
- ExcelImport::ExcelLoader
- Includes:
- DataShift::ExcelBase, DataShift::FileLoader
- Defined in:
- lib/excel_import/excel_loader.rb
Instance Method Summary collapse
-
#initialize ⇒ ExcelLoader
constructor
A new instance of ExcelLoader.
- #perform_load(options = {}) ⇒ Object
- #run(file_name, load_class, excel_instance) ⇒ Object
Constructor Details
#initialize ⇒ ExcelLoader
Returns a new instance of ExcelLoader.
22 23 24 |
# File 'lib/excel_import/excel_loader.rb', line 22 def initialize super end |
Instance Method Details
#perform_load(options = {}) ⇒ Object
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 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/excel_import/excel_loader.rb', line 37 def perform_load( = {}) allow_empty_rows = DataShift::Loaders::Configuration.call.allow_empty_rows logger.info "Starting bulk load from Excel : #{file_name}" start(file_name, ) # maps list of headers into suitable calls on the Active Record class bind_headers(headers) is_dummy_run = DataShift::Configuration.call.dummy_run begin puts 'Dummy Run - Changes will be rolled back' if is_dummy_run load_object_class.transaction do @excel.sheet_final.each_with_index do |row, current_row_idx| # next if current_row_idx == headers.idx # Excel num_rows seems to return all 'visible' rows, which appears to be greater than the actual data rows # (TODO - write spec to process .xls with a huge number of rows) # # manually have to detect when actual data ends, this isn't very smart but # got no better idea than ending once we hit the first completely empty row break if !allow_empty_rows && (row.nil? || row.empty?) logger.info "Processing Row #{current_row_idx}" contains_data = false doc_context.progress_monitor.start_monitoring # Iterate over the bindings, # For each column bound to a model operator, create a context from data in associated Excel column @binder.bindings.each do |method_binding| unless method_binding.valid? logger.warn("No binding was found for column (#{current_row_idx})") next end # If binding to a column, get the value from the cell (bindings can be to internal methods) value = method_binding.index ? row[method_binding.index] : nil context = doc_context.create_node_context(method_binding, current_row_idx, value) contains_data ||= context.contains_data? logger.info "Processing Column #{method_binding.index} (#{method_binding.pp})" begin context.process rescue if doc_context.all_or_nothing? logger.error('All or nothing set and Current Column failed so complete Row aborted') break end end end # Excel data rows not accurate, seems to have to manually detect when actual Excel data rows end break if !allow_empty_rows && contains_data == false doc_context.save_and_monitor_progress # unless next operation is update, reset the loader object doc_context.reset unless doc_context.node_context.next_update? end # all rows processed if is_dummy_run puts 'Excel loading stage done - Dummy run so Rolling Back.' raise ActiveRecord::Rollback # Don't actually create/upload to DB if we are doing dummy run end end # TRANSACTION N.B ActiveRecord::Rollback does not propagate outside of the containing transaction block rescue => e puts "ERROR: Excel loading failed : #{e.inspect}" raise e ensure report end puts 'Excel loading stage Complete.' end |
#run(file_name, load_class, excel_instance) ⇒ Object
26 27 28 29 30 31 32 33 34 |
# File 'lib/excel_import/excel_loader.rb', line 26 def run(file_name, load_class, excel_instance) @file_name = file_name @excel = excel_instance setup_load_class(load_class) logger.info("Loading objects of type #{load_object_class}") perform_load end |