Class: Importu::Sources::JSON
- Inherits:
-
Object
- Object
- Importu::Sources::JSON
- Defined in:
- lib/importu/sources/json.rb
Overview
The entire JSON file is loaded into memory. For very large files, consider using CSV or a streaming JSON parser.
Parses JSON files as import source data.
The JSON must have an array as the root element. Each array element becomes a row. The entire file is loaded into memory.
Instance Method Summary collapse
-
#close ⇒ void
Closes any resources held by this source.
-
#initialize(infile) ⇒ JSON
constructor
Creates a new JSON source.
-
#rows ⇒ Enumerator<Hash>
Returns an enumerator that yields each element as a hash.
-
#write_errors(summary, only_errors: false) ⇒ Tempfile?
Generates a JSON file with error information appended.
Constructor Details
#initialize(infile) ⇒ JSON
Creates a new JSON source.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/importu/sources/json.rb', line 37 def initialize(infile, **) owns_handle = !infile.respond_to?(:readline) @infile = owns_handle ? File.open(infile, "rb") : infile begin @infile.rewind @reader = ::JSON.parse(@infile.read) rescue ::JSON::ParserError => e raise Importu::InvalidInput, e. ensure # JSON loads entire content into memory, so we can close immediately @infile.close if owns_handle && @infile && !@infile.closed? end if @reader.nil? raise Importu::InvalidInput, "Empty document" end end |
Instance Method Details
#close ⇒ void
This method returns an undefined value.
Closes any resources held by this source.
For JSON sources, the file is already closed after initialization since the entire content is loaded into memory. This method is provided for API consistency with other sources.
63 64 65 |
# File 'lib/importu/sources/json.rb', line 63 def close # JSON source closes file immediately after reading into memory end |
#rows ⇒ Enumerator<Hash>
Returns an enumerator that yields each element as a hash.
70 71 72 73 74 |
# File 'lib/importu/sources/json.rb', line 70 def rows Enumerator.new do |yielder| @reader.each {|row| yielder.yield(row) } end end |
#write_errors(summary, only_errors: false) ⇒ Tempfile?
Generates a JSON file with error information appended.
Creates a copy of the original data with an “_errors” key containing any validation errors for each row.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/importu/sources/json.rb', line 84 def write_errors(summary, only_errors: false) return unless summary.itemized_errors.any? itemized_errors = summary.itemized_errors updated_rows = rows.each.with_index.with_object([]) do |(row, index), acc| if itemized_errors.key?(index) acc << row.merge("_errors" => itemized_errors[index].join(", ")) elsif only_errors # Requested to only include rows with new errors, row has none elsif row.key?("_errors") acc << row.dup.tap {|r| r.delete("_errors") } else acc << row end end Tempfile.new("import").tap do |file| file.write(JSON.pretty_generate(updated_rows)) file.rewind end end |