lib/iron/import/importer.rb in iron-import-0.8.5 vs lib/iron/import/importer.rb in iron-import-0.8.6

- old
+ new

@@ -125,10 +125,46 @@ importer = Importer.new(options) importer.build(&block) importer end + # Helper method for use in extracting the raw values for the first n + # rows in a given source. Uses the same format options and detection code + # used by Importer#import. If you are using a custom reader, you can pass in as + # options a lambda for :on_file or :on_stream to set the data reader to use. + def self.read_lines(num_lines, path_or_stream, options = {}, &block) + # Build a dummy importer + importer = Importer.build + + # Get the reader for our inputs + custom_reader = nil + if options[:on_file] + custom_reader = Importer::CustomReader.new(importer) + custom_reader.set_reader(:file, options[:on_file]) + + elsif options[:on_stream] + custom_reader = Importer::CustomReader.new(importer) + custom_reader.set_reader(:stream, options[:on_stream]) + end + reader = importer.find_reader(path_or_stream, options[:format], custom_reader) + + # Verify we got one + raise 'Unable to find valid reader for path' unless reader + + # What scopes (if any) should we limit our searching to? + scopes = options.delete(:scope) + if scopes && !scopes.is_a?(Array) + scopes = [scopes] + end + + # Read in the data! + reader.load(path_or_stream, scopes) do |raw_rows| + return raw_rows.slice(0...num_lines) + end + raise 'Unable to load path or stream' + end + # Ye standard constructor! def initialize(options = {}) @scopes = {} @encoding = 'UTF-8' @headerless = false @@ -294,10 +330,33 @@ def on_stream(&block) @custom_reader = CustomReader.new(self) unless @custom_reader @custom_reader.set_reader(:stream, block) end + # Helper method to find the right file/stream reader given the options and + # params passed. + def find_reader(path_or_stream, format = nil, custom_reader = nil) + reader = nil + default = custom_reader ? :custom : :auto + format ||= default + if format == :custom + # Custom format selected, use our internal custom reader + reader = custom_reader + + elsif format && format != :auto + # Explicit format requested + reader = DataReader::for_format(self, format) + + else + # Auto select + reader = DataReader::for_source(self, path_or_stream) + end + + # What did we get? + reader + end + # First call to a freshly #build'd importer, this will read the file/stream/path supplied, # validate the required values, run custom validations... basically pre-parse and # massage the supplied data. It will return true on success, or false if one # or more errors were encountered and the import failed. # @@ -330,26 +389,13 @@ # block is already conditionally called). Instead, it will return the importer to allow # chaining to #on_error or other calls. def import(path_or_stream, options = {}, &block) # Clear all our load-time state, including all rows, header locations... you name it reset - - # Get the reader for this format - default = @custom_reader ? :custom : :auto - @format = options.delete(:format) { default } - if @format == :custom - # Custom format selected, use our internal custom reader - @reader = @custom_reader - - elsif @format && @format != :auto - # Explicit format requested - @reader = DataReader::for_format(self, @format) - - else - # Auto select - @reader = DataReader::for_source(self, path_or_stream) - @format = @reader.format if @reader - end + + # Pick a reader for this stream/file + @reader = find_reader(path_or_stream, options.delete(:format), @custom_reader) + @format = @reader.format if @reader # Verify we got one unless @reader add_error("Unable to find format handler for format :#{format} on import of #{path_or_stream.class.name} source - aborting") return block ? self : false