Class: Kiba::Extend::Transforms::Merge::MultiRowLookup

Inherits:
Object
  • Object
show all
Defined in:
lib/kiba/extend/transforms/merge/multi_row_lookup.rb

Overview

Merge one or more rows from a Utils::LookupHash into source data, matching on keycolumn values

Defined Under Namespace

Classes: EmptyFieldmap, LookupTypeError

Instance Method Summary collapse

Constructor Details

#initialize(fieldmap:, lookup:, keycolumn:, constantmap: {}, conditions: {}, multikey: false, delim: Kiba::Extend.delim, null_placeholder: nil, sorter: nil) ⇒ MultiRowLookup

Note:

Interaction of specifying a sorter and multikey: true may be unexpected.

Returns a new instance of MultiRowLookup.

Parameters:

  • fieldmap (Hash{Symbol => Symbol})

    key = field in source row to merge lookup data into; value = field from lookup table whose value maps into target field

  • lookup (Hash)

    created by Utils::LookupHash. If you have registered a job as a lookup, kiba-extend takes care of creating this for you.

  • keycolumn (Symbol)

    the field in the source data that is expected to match against the keycolumn used to create the lookup hash. I.e. the field you will be matching on in the source data

  • constantmap (Hash{Symbol => String}) (defaults to: {})

    constant data to map into any rows that get data merged in from lookup table. Key = the field in source row to merge the constant value into; value = the constant value to merge in

  • conditions (Hash, Lambda) (defaults to: {})

    logic used to select which lookup rows data should be merged in from. The Hash option is pretty horrible and not at all documented. See the Lookup::RowSelectorByHash spec for some examples. The Lambda option is probably more straightforward and flexible. See Utils::Lookup::RowSelectorByLambda for examples.

  • multikey (Boolean) (defaults to: false)

    whether the source keycolumn should be treated as multivalued. I.e. it will be split on the given delim, and each resulting element of the split array will be used to retrieve rows from the lookup table to merge into this row

  • delim (String) (defaults to: Kiba::Extend.delim)

    on which to split multikey values, and to use in joining merged data in each field if multiple lookup rows are retrieved

  • null_placeholder (String) (defaults to: nil)

    such as %NULLVALUE% to merge in place of an empty/nil value. Note that this is only used if some data is being merged into the row. That is, if no lookup rows are found to merge in, all the target columns are left blank. This is useful mainly for situtations where you are merging in multiple fields which can each have multiple values, and you need to make sure groups of fields have the same number of values in them

  • sorter (nil, Kiba::Extend::Utils::Lookup::RowSorter) (defaults to: nil)

    handles sorting of lookup rows to control the order they are merged in. Without specifying a sorter, the lookup data is merged in the order it appears in the lookup table. So, if you ensure your lookup data source is sorted as desired prior to using it in a lookup, you may not need a sorter.



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/kiba/extend/transforms/merge/multi_row_lookup.rb', line 56

def initialize(fieldmap:, lookup:, keycolumn:, constantmap: {},
  conditions: {}, multikey: false, delim: Kiba::Extend.delim, null_placeholder: nil,
  sorter: nil)
  @fieldmap = fieldmap # hash of looked-up values to merge in for each merged-in row
  fail EmptyFieldmap if fieldmap.empty?

  @constantmap = constantmap # hash of constants to add for each merged-in row
  @lookup = lookup # lookuphash; should be created with csv_to_multi_hash
  fail LookupTypeError.new(lookup) unless lookup.is_a?(Hash)

  @keycolumn = keycolumn # column in main table containing value expected to be lookup key
  @multikey = multikey # should the key be treated as multivalued
  @conditions = conditions
  @delim = delim
  @null_placeholder = null_placeholder
  @sort_on = sort_on
  @sort_dir = sort_dir
  @selector = Lookup::RowSelector.call(
    conditions: conditions,
    sep: delim
  )
  @sorter = sorter
end

Instance Method Details

#process(row) ⇒ Object

Parameters:

  • row (Hash{ Symbol => String, nil })


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/kiba/extend/transforms/merge/multi_row_lookup.rb', line 81

def process(row)
  field_data = Kiba::Extend::Utils::Fieldset.new(
    fields: fieldmap.values,
    null_placeholder: null_placeholder
  )

  id_data = row.fetch(keycolumn, "")
  id_data = id_data.nil? ? "" : id_data
  ids = multikey ? id_data.split(delim) : [id_data]

  ids.each do |id|
    rtm = rows_to_merge(id, row)
    field_data.populate(rtm)
  end

  constantmap.each do |field, value|
    field_data.add_constant_values(field, value)
  end

  field_data.join_values(delim)

  field_data.hash.each do |field, value|
    row[target_field(field)] = value.blank? ? nil : value
  end

  row
end