class DataMiner::Attribute
A mapping between a local model column and a remote data source column.
@see DataMiner::ActiveRecordClassMethods#data_miner
Overview of how to define data miner scripts inside of ActiveRecord models. @see DataMiner::Step::Import#store
Telling an import step to store a column with DataMiner::Step::Import#store
@see DataMiner::Step::Import#key
Telling an import step to key on a column with DataMiner::Step::Import#key
Constants
- DEFAULT_DELIMITER
- DEFAULT_IGNORE_ERROR
- DEFAULT_SPLIT_KEEP
- DEFAULT_SPLIT_PATTERN
- DEFAULT_UPCASE
- FALSE_VALUES
- ROW_HASH_FIELD_NAME
@private
- SINGLE_SPACE
- TRUE_VALUES
activerecord-3.2.6/lib/active_record/connection_adapters/column.rb
- VALID_OPTIONS
Attributes
Which characters in a field to keep. Zero-based. @return [Range]
Date format to pass to Date.strptime @return [String]
A delimiter to be used when joining fields together into a single final value. Used when :field_number
is a Range
. Defaults to DEFAULT_DELIMITER
. @return [String]
Dictionary for translating.
You pass a Hash or something that responds to []
@return [#[]]
Index of where to find the data in the row, starting from zero.
If you pass a Range
, then multiple fields will be joined together.
@return [Integer, Range]
Ignore value conversion errors - value will be nil. @return [TrueClass, FalseClass]
Local column name. @return [String]
How to split a field. You specify two options:
:pattern
: what to split on. Defaults to DEFAULT_SPLIT_PATTERN
. :keep
: which of elements resulting from the split to keep. Defaults to DEFAULT_SPLIT_KEEP
.
@return [Hash]
A sprintf
-style format to apply. @return [String]
A static value to be used. @return [String,Numeric,TrueClass,FalseClass,Object]
@private
The block passed to a store argument. Synthesize a value by passing a proc that will receive row
and should return a final value.
Unlike past versions of DataMiner
, you pass this as a block, not with the :synthesize option.
row
will be a Hash
with string keys or (less often) an Array
@return [Proc]
Whether to upcase value. Defaults to DEFAULT_UPCASE
. @return [TrueClass,FalseClass]
Public Class Methods
@private
# File lib/data_miner/attribute.rb, line 10 def check_options(options) errors = [] if options.has_key?('dictionary') and not options['dictionary'].respond_to?(:[]) errors << %{:dictionary must respond to [], like a Hash does} end if (invalid_option_keys = options.keys - VALID_OPTIONS).any? errors << %{Invalid options: #{invalid_option_keys.map(&:inspect).to_sentence}} end errors end
@private
# File lib/data_miner/attribute.rb, line 113 def initialize(step, name, options = {}, &blk) options = options.stringify_keys if (errors = Attribute.check_options(options)).any? raise ::ArgumentError, %{[data_miner] Errors on #{inspect}: #{errors.join(';')}} end @step = step @name = name.to_s @synthesize = blk if block_given? @dictionary = options['dictionary'] @ignore_error = options.fetch 'ignore_error', DEFAULT_IGNORE_ERROR if @static_boolean = options.has_key?('static') @static = options['static'] end @date_format = options['date_format'] @field_number = options['field_number'] @field_name_settings = options['field_name'] @delimiter = options.fetch 'delimiter', DEFAULT_DELIMITER @chars = options['chars'] if split = options['split'] @split = split.stringify_keys end @upcase = options.fetch 'upcase', DEFAULT_UPCASE @sprintf = options['sprintf'] end
Public Instance Methods
Where to find the data in the row. If more than one field name, values are joined with a space. @return [Array<String>]
# File lib/data_miner/attribute.rb, line 152 def field_name return @field_name if defined?(@field_name) @field_name = if @field_name_settings.is_a?(::Array) @field_name_settings.map(&:to_s) elsif @field_name_settings.is_a?(::String) or @field_name_settings.is_a?(::Symbol) [ @field_name_settings.to_s ] elsif hstore? [ hstore_key ] else [ name ] end end
# File lib/data_miner/attribute.rb, line 271 def hstore? return @hstore_boolean if defined?(@hstore_boolean) @hstore_boolean = name.include?('.') end
@private
# File lib/data_miner/attribute.rb, line 139 def hstore_column return @hstore_column if defined?(@hstore_column) @hstore_column = name.split('.', 2)[0] end
@private
# File lib/data_miner/attribute.rb, line 145 def hstore_key return @hstore_key if defined?(@hstore_key) @hstore_key = name.split('.', 2)[1] end
# File lib/data_miner/attribute.rb, line 188 def read(row) if not column_exists? raise RuntimeError, "[data_miner] Table #{model.table_name} does not have column #{(hstore? ? hstore_column : name).inspect}" end value = if static? static elsif synthesize synthesize.call(row) elsif field_number if field_number.is_a?(::Range) field_number.map { |n| row[n] }.join(delimiter) else row[field_number] end elsif field_name == ROW_HASH_FIELD_NAME row.row_hash elsif row.is_a?(::Hash) or row.is_a?(::ActiveSupport::OrderedHash) field_name.length > 1 ? row.values_at(*field_name).join(SINGLE_SPACE) : row[field_name[0]] end if value.nil? return end if value.is_a? ::ActiveRecord::Base return value end value = value.to_s if boolean_column? if TRUE_VALUES.include?(value) return true elsif FALSE_VALUES.include?(value) return false else return end end if number_column? period_position = value.rindex '.' comma_position = value.rindex ',' # assume that ',' is a thousands separator and '.' is a decimal point unless we have evidence to the contrary if period_position and comma_position and comma_position > period_position # uncommon euro style 1.000,53 value = value.delete('.').gsub(',', '.') elsif comma_position and comma_position > (value.length - 4) # uncommon euro style 1000,53 value = value.gsub(',', '.') elsif comma_position # more common 1,000[.00] style - still don't want commas value = value.delete(',') end end if chars value = value[chars] end if split pattern = split.fetch 'pattern', DEFAULT_SPLIT_PATTERN keep = split.fetch 'keep', DEFAULT_SPLIT_KEEP value = value.to_s.split(pattern)[keep].to_s end if value.blank? # TODO false is "blank" return end value = DataMiner.compress_whitespace value if upcase value = DataMiner.upcase value end if sprintf value = sprintf % value.to_f end if date_format value = Date.strptime value.to_s, date_format end if dictionary value = dictionary[value] end value rescue if ignore_error DataMiner.logger.debug { "Error in #{name}: #{$!.message}" } else raise $! end end
@private
# File lib/data_miner/attribute.rb, line 166 def set_from_row(local_record, remote_row) new_value = read remote_row if hstore? local_record.send(hstore_column)[hstore_key] = new_value else local_record.send("#{name}=", new_value) end end
@private
# File lib/data_miner/attribute.rb, line 176 def updates(remote_row) v = read remote_row if hstore? { hstore_column => { hstore_key => v } } else { name => v } end end
Private Instance Methods
# File lib/data_miner/attribute.rb, line 309 def boolean_column? return @boolean_column_boolean if defined?(@boolean_column_boolean) if hstore? @boolean_column_boolean = false else @boolean_column_boolean = (model.columns_hash[name].type == :boolean) end end
# File lib/data_miner/attribute.rb, line 282 def column_exists? return @column_exists_boolean if defined?(@column_exists_boolean) if hstore? @column_exists_boolean = model.column_names.include? hstore_column else @column_exists_boolean = model.column_names.include? name end end
# File lib/data_miner/attribute.rb, line 278 def model step.model end
# File lib/data_miner/attribute.rb, line 300 def number_column? return @number_column_boolean if defined?(@number_column_boolean) if hstore? @number_column_boolean = false else @number_column_boolean = model.columns_hash[name].number? end end
# File lib/data_miner/attribute.rb, line 318 def static? @static_boolean end
# File lib/data_miner/attribute.rb, line 291 def text_column? return @text_column_boolean if defined?(@text_column_boolean) if hstore? @text_column_boolean = true else @text_column_boolean = model.columns_hash[name].text? end end