lib/etl/control/destination.rb in activewarehouse-etl-0.4.0 vs lib/etl/control/destination.rb in activewarehouse-etl-0.5.0

- old
+ new

@@ -1,28 +1,56 @@ module ETL #:nodoc: module Control #:nodoc: + # Base class for destinations. class Destination - attr_reader :control, :configuration, :mapping - attr_accessor :buffer_size, :current_row, :unique + # Read-only accessor for the ETL::Control::Control instance + attr_reader :control + # Read-only accessor for the configuration Hash + attr_reader :configuration + + # Read-only accessor for the destination mapping Hash + attr_reader :mapping + + # Accessor to the buffer size + attr_accessor :buffer_size + + # Unique flag. + attr_accessor :unique + class << self + # Get the destination class for the specified name. + # + # For example if name is :database or 'database' then the DatabaseDestination class + # is returned def class_for_name(name) ETL::Control.const_get("#{name.to_s.classify}Destination") end end + # Initialize the destination + # + # Arguments: + # * <tt>control</tt>: The ETL::Control::Control instance + # * <tt>configuration</tt>: The configuration Hash + # * <tt>mapping</tt>: The mapping Hash + # + # Options: + # * <tt>:buffer_size</tt>: The output buffer size (default 1000 records) def initialize(control, configuration, mapping) @control = control @configuration = configuration @mapping = mapping @buffer_size = configuration[:buffer_size] ||= 1000 end + # Get the current row number def current_row @current_row ||= 1 end + # Write the given row def write(row) buffer << row flush if buffer.length >= buffer_size end @@ -34,15 +62,21 @@ # Abstract method def close raise NotImplementedError, "close method must be implemented by subclasses" end + def errors + @errors ||= [] + end + protected + # Access the buffer def buffer @buffer ||= [] end + # Access the generators map def generators @generators ||= {} end # Get the order of elements from the source order @@ -74,18 +108,25 @@ # unique option is specified def compound_key_constraints @compound_key_constraints ||= {} end - # Add any virtual fields to the row + # Add any virtual fields to the row. Virtual rows will get their value from one of the following: + # * If the mapping is a Class, then an object which implements the next method + # * If the mapping is a Symbol, then the XGenerator where X is the classified symbol + # * If the mapping is a Proc, then it will be called with the row + # * Otherwise the value itself will be assigned to the field def add_virtuals!(row) if mapping[:virtual] mapping[:virtual].each do |key,value| # Engine.logger.debug "Mapping virtual #{key}/#{value} for row #{row}" case value + when Class + generator = generators[key] ||= value.new + row[key] = generator.next when Symbol - generators[key] ||= ETL::Generator::Generator.class_for_name(value).new - row[key] = generators[key].next + generator = generators[key] ||= ETL::Generator::Generator.class_for_name(value).new + row[key] = generator.next when Proc row[key] = value.call(row) else row[key] = value end \ No newline at end of file