burner 1.11.0 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f687d9818e7a090c0999f144096eef52c5ba7093a069a8d2ef784f5abdb859d7
4
- data.tar.gz: cae3bb23c2671ab69263fe7359c93a47777c72fc387ab93a03006c38a2bc83cd
3
+ metadata.gz: ce126372d1a0fa7d4873cb58c354372a13a013a56f89f4814950eb497e9fb095
4
+ data.tar.gz: 0efcd55a83ef5b1c0cc716cafeae2204f4207c894419a3e40450d46e505b8ca7
5
5
  SHA512:
6
- metadata.gz: 3d1740b55ec51e3459092d99165f75197dcad75d2dcce28ae285ed9dc1e1fcbb2a85002f8abeb868e0bc388424e8e85056bab1b41a54046023d06fbd836f0598
7
- data.tar.gz: bffbcf8567d03252bc04fb8e207674595b271635da2ef4cec963cd6ac329e4e58194167f0b474dc522785cbaef10a239b504e12825c56fb9d55042f4733b1840
6
+ metadata.gz: 5ebf524b5794577e5d287a917a52207962241ad98aa68c75069aee65d0bfeb06ae4a20af84b4ce2568449f72c2611922f69cbc130fb91b859c60f3fd28e34465
7
+ data.tar.gz: 18db46b8876228fec2357672b6abe6cf07a86434ab1595667d18c230122d2dfac3ae03cf0794a097be7fc75c42444a368a7ede5ff8207eca5defec57c6022775
data/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ # 1.12.0 (August 12th, 2021)
2
+
3
+ Enhanced Job:
4
+
5
+ * b/collection/flat_file_parse now supports key mappings.
6
+
7
+ Added Jobs:
8
+
9
+ * b/collection/prepend (alias for unshift)
10
+ * b/collection/unshift
11
+
1
12
  # 1.11.0 (May 17th, 2021)
2
13
 
3
14
  Added Jobs:
data/README.md CHANGED
@@ -266,7 +266,7 @@ This library only ships with very basic, rudimentary jobs that are meant to just
266
266
  * **b/collection/arrays_to_objects** [mappings, register]: Convert an array of arrays to an array of objects.
267
267
  * **b/collection/coalesce** [grouped_register, insensitive, key_mappings, keys, register, separator]: Merge two datasets together based on the key values of one dataset (array) with a grouped dataset (hash). If insensitive (false by default) is true then each key's value will be converted/coerced to a lowercase string.
268
268
  * **b/collection/concatenate** [from_registers, to_register]: Concatenate each from_register's value and place the newly concatenated array into the to_register. Note: this does not do any deep copying and should be assumed it is shallow copying all objects.
269
- * **b/collection/flat_file_parse** [keys_register, register, separator]: Map an array of arrays to an array of hashes. These keys can be realized at run-time as they are pulled from the first entry in the array. The `keys_register` will also be set to the keys used for mapping.
269
+ * **b/collection/flat_file_parse** [keys_register, register, separator, key_mappings]: Map an array of arrays to an array of hashes. These keys can be realized at run-time as they are pulled from the first entry in the array. The `keys_register` will also be set to the keys used for mapping. Only keys that are mapped will be included in the `keys_register` array if `key_mappings` are defined. Otherwise all keys that are pulled from the first entry in the `register` will be included in the `keys_register`.
270
270
  * **b/collection/graph** [config, key, register]: Use [Hashematics](https://github.com/bluemarblepayroll/hashematics) to turn a flat array of objects into a deeply nested object tree.
271
271
  * **b/collection/group** [insensitive, keys, register, separator]: Take a register's value (an array of objects) and group the objects by the specified keys. If insensitive (false by default) is true then each key's value will be converted/coerced to a lowercase string.
272
272
  * **b/collection/nested_aggregate** [register, key_mappings, key, separator]: Traverse a set of objects, resolving key's value for each object, optionally copying down key_mappings to the child records, then merging all the inner records together.
@@ -275,9 +275,11 @@ This library only ships with very basic, rudimentary jobs that are meant to just
275
275
  * **b/collection/only_keys** [keys_register, register, separator]: Limit an array of objects' keys to a specified set of keys. These keys can be realized at run-time as they are pulled from another register (`keys_register`) thus making it dynamic.
276
276
  * **b/collection/pivot** [unique_keys, insensitive, other_keys, pivot_key, pivot_value_key, register, separator]:
277
277
  Take an array of objects and pivot a key into multiple keys. It essentially takes all the values for a key and creates N number of keys (one per value.) Under the hood it uses HashMath's [Record](https://github.com/bluemarblepayroll/hash_math#record-the-hash-prototype) and [Table](https://github.com/bluemarblepayroll/hash_math#table-the-double-hash-hash-of-hashes) classes.
278
+ * **b/collection/prepend** [from_registers, to_register]: Alias for b\collection\unshift.
278
279
  * **b/collection/shift** [amount, register]: Remove the first N number of elements from an array.
279
280
  * **b/collection/transform** [attributes, exclusive, separator, register]: Iterate over all objects and transform each key per the attribute transformers specifications. If exclusive is set to false then the current object will be overridden/merged. Separator can also be set for key path support. This job uses [Realize](https://github.com/bluemarblepayroll/realize), which provides its own extendable value-transformation pipeline. If an attribute is not set with `explicit: true` then it will automatically start from the key's value from the record. If `explicit: true` is started, then it will start from the record itself.
280
281
  * **b/collection/unpivot** [pivot_set, register]: Take an array of objects and unpivot specific sets of keys into rows. Under the hood it uses [HashMath's Unpivot class](https://github.com/bluemarblepayroll/hash_math#unpivot-hash-key-coalescence-and-row-extrapolation).
282
+ * **b/collection/unshift** [from_registers, register]: Adds the values of the `from_registers` to the `register` array. All existing elements in the `register` array will be shifted upwards.
281
283
  * **b/collection/validate** [invalid_register, join_char, message_key, register, separator, validations]: Take an array of objects, run it through each declared validator, and split the objects into two registers. The valid objects will be split into the current register while the invalid ones will go into the invalid_register as declared. Optional arguments, join_char and message_key, help determine the compiled error messages. The separator option can be utilized to use dot-notation for validating keys. See each validation's options by viewing their classes within the `lib/modeling/validations` directory.
282
284
  * **b/collection/values** [include_keys, register]: Take an array of objects and call `#values` on each object. If include_keys is true (it is false by default), then call `#keys` on the first object and inject that as a "header" object.
283
285
  * **b/collection/zip** [base_register, register, with_register]: Combines `base_register` and `with_register`s' data to form one single array in `register`. It will combine each element, positionally in each array to form the final array. For example: ['hello', 'bugs'] + ['world', 'bunny'] => [['hello', 'world'], ['bugs', 'bunny']]
@@ -13,17 +13,20 @@ module Burner
13
13
  # Add on a register attribute to the configuration for a job. This indicates that a job
14
14
  # either accesses and/or mutates the payload's registers.
15
15
  class JobWithDynamicKeys < JobWithRegister
16
- attr_reader :keys_register,
16
+ attr_reader :key_mappings,
17
+ :keys_register,
17
18
  :resolver
18
19
 
19
20
  def initialize(
20
21
  keys_register:,
21
22
  name: '',
22
23
  register: DEFAULT_REGISTER,
23
- separator: BLANK
24
+ separator: BLANK,
25
+ key_mappings: []
24
26
  )
25
27
  super(name: name, register: register)
26
28
 
29
+ @key_mappings = Modeling::KeyMapping.array(key_mappings)
27
30
  @keys_register = keys_register.to_s
28
31
  @resolver = Objectable.resolver(separator: separator)
29
32
 
data/lib/burner/jobs.rb CHANGED
@@ -33,9 +33,11 @@ module Burner
33
33
  register 'b/collection/objects_to_arrays', Library::Collection::ObjectsToArrays
34
34
  register 'b/collection/only_keys', Library::Collection::OnlyKeys
35
35
  register 'b/collection/pivot', Library::Collection::Pivot
36
+ register 'b/collection/prepend', Library::Collection::Unshift
36
37
  register 'b/collection/shift', Library::Collection::Shift
37
38
  register 'b/collection/transform', Library::Collection::Transform
38
39
  register 'b/collection/unpivot', Library::Collection::Unpivot
40
+ register 'b/collection/unshift', Library::Collection::Unshift
39
41
  register 'b/collection/values', Library::Collection::Values
40
42
  register 'b/collection/validate', Library::Collection::Validate
41
43
  register 'b/collection/zip', Library::Collection::Zip
@@ -27,6 +27,7 @@ require_relative 'library/collection/pivot'
27
27
  require_relative 'library/collection/shift'
28
28
  require_relative 'library/collection/transform'
29
29
  require_relative 'library/collection/unpivot'
30
+ require_relative 'library/collection/unshift'
30
31
  require_relative 'library/collection/validate'
31
32
  require_relative 'library/collection/values'
32
33
  require_relative 'library/collection/zip'
@@ -11,8 +11,10 @@ module Burner
11
11
  module Library
12
12
  module Collection
13
13
  # Convert an array of arrays to an array of objects. The difference between this
14
- # job and ArraysToObjects is that this one does not take in mappings and instead
14
+ # job and ArraysToObjects is that this one does not require mappings and instead
15
15
  # will use the first entry as the array of keys to positionally map to.
16
+ # If key mappings are specified then the keys register will only contain
17
+ # the keys that are mapped. The register will still contain mapped and unmapped keys.
16
18
  #
17
19
  # For example, if a register had this:
18
20
  #
@@ -22,35 +24,123 @@ module Burner
22
24
  #
23
25
  # [{ 'id' => 1, 'first' => frank, 'last' => rizzo }]
24
26
  #
25
- # As a side-effect, the keys_register would result in this:
27
+ # As a side-effect, the keys_register would result in this, if no key mappings were specified:
26
28
  #
27
29
  # ['id', 'first', 'last']
28
30
  #
31
+ # If key mappings are specified:
32
+ # [
33
+ #
34
+ # {
35
+ # from: 'first',
36
+ # to: 'first_name'
37
+ # }
38
+ # {
39
+ # from: 'iban',
40
+ # to: 'iban_number'
41
+ # }
42
+ # ]
43
+ # Then the register will now be:
44
+ # [{ 'id' => 1, 'first_name' => frank, 'last' => rizzo }]
45
+ #
46
+ # And the keys_register will now contain:
47
+ # ['first_name']
48
+ #
49
+ # Since 'last' did not have a key mapping entry it does not exist in the keys register.
50
+ # In addition, even though 'iban' does have a key mapping it does not exist in the
51
+ # register's payload, so it also does not exist in the keys register.
52
+ #
29
53
  # Expected Payload[register] input: array of arrays.
30
54
  # Payload[register] output: An array of hashes.
55
+ # Payload[keys_register] output; An array of key names.
31
56
  class FlatFileParse < JobWithDynamicKeys
32
57
  def perform(output, payload)
33
- objects = array(payload[register])
34
- keys = array(objects.shift)
35
- count = objects.length
58
+ objects = array(payload[register])
59
+ keys = array(objects.shift)
60
+ count = objects.length
61
+ mapped_keys = update_keys_using_mappings(keys, output)
62
+
63
+ payload[register] = objects.map { |object| transform(object, mapped_keys, output) }
64
+ payload[keys_register] = get_mapped_keys(mapped_keys)
36
65
 
37
- output.detail("Mapping #{count} array(s) to key(s): #{keys.join(', ')}")
66
+ output.detail("Mapping #{count} array(s)")
38
67
 
39
- payload[register] = objects.map { |object| transform(object, keys) }
40
- payload[keys_register] = keys
68
+ output.detail("Mapping keys register array to: #{payload[keys_register].join(', ')}")
41
69
  end
42
70
 
43
71
  private
44
72
 
45
- def transform(object, keys)
73
+ def transform(object, keys, output)
46
74
  object.each_with_object({}).with_index do |(value, memo), index|
47
75
  next if index >= keys.length
48
76
 
49
- key = keys[index]
77
+ key_hash = keys[index]
78
+
79
+ key = key_hash[:unmapped_key_name]
80
+
81
+ mapped_key = key_hash[:mapped_key_name]
82
+
83
+ key = mapped_key if mapped_key
50
84
 
51
85
  resolver.set(memo, key, value)
86
+
87
+ output.detail("Using key #{key}")
88
+ end
89
+ end
90
+
91
+ def get_mapped_keys(mapped_keys)
92
+ mapped_keys.each_with_object([]) do |mapped_key_hash, memo|
93
+ mapped_key = mapped_key_hash[:mapped_key_name]
94
+
95
+ memo << mapped_key if mapped_key
96
+ end
97
+ end
98
+
99
+ def update_keys_using_mappings(keys, output)
100
+ if key_mappings.count.positive?
101
+ populate_key_hashes_from_mappings(keys, output)
102
+ else
103
+ populate_key_hashes_without_mappings(keys)
104
+ end
105
+ end
106
+
107
+ def populate_key_hashes_from_mappings(keys, output)
108
+ keys.each_with_object([]) do |key, memo|
109
+ mapped_key_name = find_key_name_to_use_from_mappings(key, output)
110
+
111
+ mapped_key_name = nil if key == mapped_key_name
112
+
113
+ memo << create_key_hash(key, mapped_key_name)
52
114
  end
53
115
  end
116
+
117
+ def populate_key_hashes_without_mappings(keys)
118
+ keys.each_with_object([]) do |key, memo|
119
+ memo << create_key_hash(key, key)
120
+ end
121
+ end
122
+
123
+ def create_key_hash(unmapped_key_name, mapped_key_name)
124
+ { unmapped_key_name: unmapped_key_name, mapped_key_name: mapped_key_name }
125
+ end
126
+
127
+ def find_key_name_to_use_from_mappings(key, output)
128
+ key_to_use = key
129
+
130
+ key_mappings.each do |key_mapping|
131
+ next unless key_mapping.from.downcase == key.downcase
132
+
133
+ key_to_use = populate_key_to_use(key_mapping)
134
+ output.detail("Using key_mapping from key #{key} to #{key_to_use}")
135
+ break
136
+ end
137
+
138
+ key_to_use
139
+ end
140
+
141
+ def populate_key_to_use(key_mapping)
142
+ key_mapping.to unless key_mapping.to.empty?
143
+ end
54
144
  end
55
145
  end
56
146
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2020-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ module Burner
11
+ module Library
12
+ module Collection
13
+ # Adds the values of the from_registers to the to_register array.
14
+ # All existing elements in the register array will be shifted upwards.
15
+ #
16
+ # Expected Payload[from_registers] input: Array containing names of registers
17
+ # whose values to prepend.
18
+ # Payload[register] output: An array with the from_registers'
19
+ # payload added to the beginning.
20
+ class Unshift < JobWithRegister
21
+ attr_reader :from_registers
22
+
23
+ def initialize(from_registers: [], name: '', register: DEFAULT_REGISTER)
24
+ super(name: name, register: register)
25
+
26
+ @from_registers = Array(from_registers)
27
+
28
+ freeze
29
+ end
30
+
31
+ def perform(output, payload)
32
+ output.detail("Prepending registers: '#{from_registers}' to: '#{register}'")
33
+
34
+ payload_register = array(payload[register])
35
+
36
+ from_registers.each do |from_register|
37
+ from_register_value = payload[from_register]
38
+
39
+ payload_register.unshift(from_register_value)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -8,5 +8,5 @@
8
8
  #
9
9
 
10
10
  module Burner
11
- VERSION = '1.11.0'
11
+ VERSION = '1.12.0'
12
12
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: burner
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.11.0
4
+ version: 1.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Ruggio
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-05-18 00:00:00.000000000 Z
11
+ date: 2021-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: acts_as_hashable
@@ -258,6 +258,7 @@ files:
258
258
  - lib/burner/library/collection/shift.rb
259
259
  - lib/burner/library/collection/transform.rb
260
260
  - lib/burner/library/collection/unpivot.rb
261
+ - lib/burner/library/collection/unshift.rb
261
262
  - lib/burner/library/collection/validate.rb
262
263
  - lib/burner/library/collection/values.rb
263
264
  - lib/burner/library/collection/zip.rb