lib/data_miner/dictionary.rb in data_miner-2.0.1 vs lib/data_miner/dictionary.rb in data_miner-2.0.2
- old
+ new
@@ -1,60 +1,82 @@
require 'remote_table'
class DataMiner
+ # An easy way to translate data before importing it using an intermediate table.
class Dictionary
DEFAULT_CASE_SENSITIVE = true
+ # What field in the dictionary holds the lookup key.
+ #
+ # In other words, the column we scan down to find an entry.
+ #
+ # @return [String]
attr_reader :key_name
+
+ # What field in the dictionary holds the final value.
+ #
+ # @return [String]
attr_reader :value_name
+
+ # A +sprintf+-style format to be applied.
+ # @return [String]
attr_reader :sprintf
+
+ # The URL of the dictionary. It must be a CSV.
+ # @return [String]
attr_reader :url
+
+ # Whether to be case-sensitive with lookups. Defaults to false.
+ # @return [TrueClass, FalseClass]
attr_reader :case_sensitive
+ # @private
def initialize(options = {})
options = options.symbolize_keys
@url = options[:url]
- @key_name = options[:input]
- @value_name = options[:output]
+ @key_name = options[:input].to_s
+ @value_name = options[:output].to_s
@sprintf = options[:sprintf]
@case_sensitive = options.fetch :case_sensitive, DEFAULT_CASE_SENSITIVE
@table_mutex = ::Mutex.new
end
+ # Look up a translation for a value.
+ #
+ # @return [nil, String]
+ def lookup(value)
+ normalized_value = normalize_for_comparison value
+ if match = table.detect { |entry| entry[key_name] == normalized_value }
+ match[value_name].to_s
+ end
+ end
+
+ private
+
def table
@table || @table_mutex.synchronize do
- @table ||= ::RemoteTable.new(url).to_a # make sure it's fully cached
+ @table ||= ::RemoteTable.new(url).map do |entry|
+ entry[key_name] = normalize_for_comparison entry[key_name]
+ entry
+ end
end
end
def refresh
@table = nil
end
-
- def lookup(key)
- find key_name, key, value_name, {:sprintf => sprintf, :case_sensitive => case_sensitive}
- end
-
- def find(key_name, key, value_name, options = {})
- normalized_key = normalize_for_comparison(key, options)
- if match = table.detect { |row| normalized_key == normalize_for_comparison(row[key_name.to_s], options) }
- match[value_name.to_s].to_s
- end
- end
-
- private
- def normalize_for_comparison(str, options = {})
+ def normalize_for_comparison(str)
if sprintf
if sprintf.end_with?('f')
str = str.to_f
elsif sprintf.end_with?('d')
str = str.to_i
end
str = sprintf % str
end
str = DataMiner.compress_whitespace str
- unless options[:case_sensitive]
+ unless case_sensitive
str = DataMiner.downcase str
end
str
end
end