db_fuel 2.0.1 → 2.1.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: 81819bf8d353ae3425d90360089da3857aa5ccaeb56ffc499557bd036d318493
4
- data.tar.gz: 32ee04a7d5c25f3f6b40dae72809aa8752d00e9736abf03bde7b0a08ef18f86a
3
+ metadata.gz: fba199a30d6af2387ecafebfbaa2a946a25f6a8630558c838d1967f8d7c41d51
4
+ data.tar.gz: 80aaa216b30b90477bf50b7f4a3e139e465870c129fa8a1030c34c0b0ce3d7b8
5
5
  SHA512:
6
- metadata.gz: b9bf6c8852f0da644839fc0883daceae2808c4646e5a26581da878dca9f09c71e7b3de887c0ac4f2107a3a7cdd3e8ccc6e58f70e01a5717bbae5842aa6691387
7
- data.tar.gz: c1c2fb22e493cecc947d1f597ba91118c5f62acd1dd4263842b3004aa8d18943ff8910600ab2a8bde39a54eb50de8db220e309941ff439a02d19895fec7d8d97
6
+ metadata.gz: 87ab66e3f9705fa672f0701cc500df58c218f0332a63809d94823c1eed1a0bd521418110bd95fabe63db1310079e0fba8b9db78d0bbae7a84a85096492afc122
7
+ data.tar.gz: a6bc96a500ff5dc25728d5ff933239e21536aded8f4ae94a7d375ceef29d5157e12746039838e4358be83a107e8be5fdc88bd049de9b241425c5d34a23974c6b
data/CHANGELOG.md CHANGED
@@ -1,6 +1,14 @@
1
+
2
+ # 2.1.0 (May 19th, 2021)
3
+
4
+ Additions:
5
+
6
+ * Added keys_register to all db_fuel/active_record jobs.
7
+
1
8
  # 2.0.1 (March 18th, 2021)
2
9
 
3
10
  Changes:
11
+
4
12
  * Updated attribute_renderer_set to avoid an evaluation time issue with acts_as_hashable.
5
13
 
6
14
  # 2.0.0 (March 16th, 2021)
data/README.md CHANGED
@@ -24,11 +24,11 @@ Refer to the [Burner](https://github.com/bluemarblepayroll/burner) library for m
24
24
 
25
25
  ### ActiveRecord Jobs
26
26
 
27
- * **db_fuel/active_record/find_or_insert** [name, table_name, attributes, debug, primary_keyed_column, register, separator, timestamps, unique_attributes]: An extension of the `db_fuel/active_record/insert` job that adds an existence check before SQL insertion. The `unique_attributes` will be converted to WHERE clauses for performing the existence check.
28
- * **db_fuel/active_record/insert** [name, table_name, attributes, debug, primary_keyed_column, register, separator, timestamps]: This job can take the objects in a register and insert them into a database table. If primary_keyed_column is specified then its key will be set to the primary key. Note that composite primary keys are not supported. Attributes defines which object properties to convert to SQL. Refer to the class and constructor specification for more detail.
29
- * **db_fuel/active_record/update_all** [name, table_name, attributes, debug, register, separator, timestamps, unique_attributes]: This job can take the objects in a register and updates them within a database table. Attributes defines which object properties to convert to SQL SET clauses while unique_attributes translate to WHERE clauses. One or more records may be updated at a time. Refer to the class and constructor specification for more detail.
30
- * **db_fuel/active_record/update** [name, table_name, attributes, debug, register, primary_keyed_column, separator, timestamps, unique_attributes]: This job can take the unique objects in a register and updates them within a database table. Attributes defines which object properties to convert to SQL SET clauses while unique_attributes translate to WHERE clauses to find the records to update. The primary_keyed_column is used to update the unique record. Only one record will be updated per statement. Note that composite primary keys are not supported. Refer to the class and constructor specification for more detail.
31
- * **db_fuel/active_record/upsert** [name, table_name, attributes, debug, primary_keyed_column, register, separator, timestamps, unique_attributes]: This job can take the objects in a register and either inserts or updates them within a database table. Attributes defines which object properties to convert to SQL SET clauses while each key in unique_attributes become a WHERE clause in order to check for the existence of a specific record. The updated record will use the primary_keyed_column specified to perform the UPDATE operation. Note that composite primary keys are not supported. Refer to the class and constructor specification for more detail.
27
+ * **db_fuel/active_record/find_or_insert** [name, table_name, attributes, debug, primary_keyed_column, keys_register, register, separator, timestamps, unique_attributes]: An extension of the `db_fuel/active_record/insert` job that adds an existence check before SQL insertion. The `unique_attributes` will be converted to WHERE clauses for performing the existence check.
28
+ * **db_fuel/active_record/insert** [name, table_name, attributes, debug, primary_keyed_column, keys_register, register, separator, timestamps]: This job can take the objects in a register and insert them into a database table. If primary_keyed_column is specified then its key will be set to the primary key. Note that composite primary keys are not supported. Attributes defines which object properties to convert to SQL. Refer to the class and constructor specification for more detail.
29
+ * **db_fuel/active_record/update_all** [name, table_name, attributes, debug, keys_register, register, separator, timestamps, unique_attributes]: This job can take the objects in a register and updates them within a database table. Attributes defines which object properties to convert to SQL SET clauses while unique_attributes translate to WHERE clauses. One or more records may be updated at a time. Refer to the class and constructor specification for more detail.
30
+ * **db_fuel/active_record/update** [name, table_name, attributes, debug, keys_register, register, primary_keyed_column, separator, timestamps, unique_attributes]: This job can take the unique objects in a register and updates them within a database table. Attributes defines which object properties to convert to SQL SET clauses while unique_attributes translate to WHERE clauses to find the records to update. The primary_keyed_column is used to update the unique record. Only one record will be updated per statement. Note that composite primary keys are not supported. Refer to the class and constructor specification for more detail.
31
+ * **db_fuel/active_record/upsert** [name, table_name, attributes, debug, primary_keyed_column, keys_register, register, separator, timestamps, unique_attributes]: This job can take the objects in a register and either inserts or updates them within a database table. Attributes defines which object properties to convert to SQL SET clauses while each key in unique_attributes become a WHERE clause in order to check for the existence of a specific record. The updated record will use the primary_keyed_column specified to perform the UPDATE operation. Note that composite primary keys are not supported. Refer to the class and constructor specification for more detail.
32
32
 
33
33
  ### Dbee Jobs
34
34
 
@@ -331,7 +331,7 @@ Each database record should have been updated with their new respective middle n
331
331
 
332
332
  #### Upserting Records
333
333
 
334
- Let's say we don't know if these chart_number values already exist or not.
334
+ Let's say we don't know if these chart_number values already exist or not.
335
335
  So we want db_fuel to either insert a record if the chart_number doesn't exist or update the record if the chart_number already exists.
336
336
 
337
337
  ````ruby
@@ -378,6 +378,10 @@ Notes:
378
378
 
379
379
  * The `unique_attributes` translate to WHERE clauses.
380
380
  * Set `debug: true` to print out each UPDATE statement in the output (not for production use.)
381
+
382
+ #### Limiting The Columns Being Inserted/Updated
383
+
384
+ All the db_fuel/active_record/* jobs now feature an optional `keys_register` option. If this is set, the register will be read and used as a key filter for which fields to set. For example, if you configure a db_fuel/active_record/insert job to update A, B, C, and D, but your keys_register contains [A,B] then only A and B will be inserted/set. This is helpful in scenarios where you may want to outline how to update _all_ possible fields but your input set only contains a subset of those fields and you do not wish to set the others to null.
381
385
  ## Contributing
382
386
 
383
387
  ### Development Environment Configuration
@@ -22,6 +22,7 @@ module DbFuel
22
22
  attr_reader :attribute_renderers,
23
23
  :db_provider,
24
24
  :debug,
25
+ :keys_register,
25
26
  :resolver,
26
27
  :attribute_renderers_set
27
28
 
@@ -30,12 +31,14 @@ module DbFuel
30
31
  name: '',
31
32
  attributes: [],
32
33
  debug: false,
34
+ keys_register: nil,
33
35
  register: Burner::DEFAULT_REGISTER,
34
36
  separator: ''
35
37
  )
36
38
  super(name: name, register: register)
37
39
 
38
- @resolver = Objectable.resolver(separator: separator)
40
+ @keys_register = keys_register.to_s
41
+ @resolver = Objectable.resolver(separator: separator)
39
42
  @attribute_renderers_set = Modeling::AttributeRendererSet.new(resolver: resolver,
40
43
  attributes: attributes)
41
44
  @db_provider = DbProvider.new(table_name)
@@ -49,6 +52,16 @@ module DbFuel
49
52
 
50
53
  output.detail(message)
51
54
  end
55
+
56
+ def resolve_key_set(output, payload)
57
+ return Set.new if keys_register.empty?
58
+
59
+ keys = array(payload[keys_register]).map(&:to_s).to_set
60
+
61
+ output.detail("Limiting to only keys: #{keys.to_a.join(', ')}") if keys.any?
62
+
63
+ keys
64
+ end
52
65
  end
53
66
  end
54
67
  end
@@ -57,6 +57,7 @@ module DbFuel
57
57
  name: '',
58
58
  attributes: [],
59
59
  debug: false,
60
+ keys_register: nil,
60
61
  primary_keyed_column: nil,
61
62
  register: Burner::DEFAULT_REGISTER,
62
63
  separator: '',
@@ -66,6 +67,7 @@ module DbFuel
66
67
 
67
68
  super(
68
69
  name: name,
70
+ keys_register: keys_register,
69
71
  table_name: table_name,
70
72
  attributes: attributes,
71
73
  debug: debug,
@@ -82,6 +84,7 @@ module DbFuel
82
84
  total_existed = 0
83
85
 
84
86
  payload[register] = array(payload[register])
87
+ keys = resolve_key_set(output, payload)
85
88
 
86
89
  payload[register].each do |row|
87
90
  exists = find_record(output, row, payload.time)
@@ -91,7 +94,7 @@ module DbFuel
91
94
  next
92
95
  end
93
96
 
94
- insert_record(output, row, payload.time)
97
+ insert_record(output, row, payload.time, keys)
95
98
 
96
99
  total_inserted += 1
97
100
  end
@@ -45,6 +45,7 @@ module DbFuel
45
45
  # to the current UTC timestamp.
46
46
  def initialize(
47
47
  table_name:,
48
+ keys_register: nil,
48
49
  name: '',
49
50
  attributes: [],
50
51
  debug: false,
@@ -53,11 +54,11 @@ module DbFuel
53
54
  separator: '',
54
55
  timestamps: true
55
56
  )
56
-
57
57
  attributes = Burner::Modeling::Attribute.array(attributes)
58
58
 
59
59
  super(
60
60
  name: name,
61
+ keys_register: keys_register,
61
62
  table_name: table_name,
62
63
  attributes: attributes,
63
64
  debug: debug,
@@ -70,8 +71,11 @@ module DbFuel
70
71
 
71
72
  def perform(output, payload)
72
73
  payload[register] = array(payload[register])
74
+ keys = resolve_key_set(output, payload)
75
+
76
+ output.detail("Inserting #{payload[register].count} record(s)")
73
77
 
74
- payload[register].each { |row| insert_record(output, row, payload.time) }
78
+ payload[register].each { |row| insert_record(output, row, payload.time, keys) }
75
79
  end
76
80
  end
77
81
  end
@@ -57,6 +57,7 @@ module DbFuel
57
57
  attributes: [],
58
58
  debug: false,
59
59
  primary_keyed_column: nil,
60
+ keys_register: nil,
60
61
  register: Burner::DEFAULT_REGISTER,
61
62
  separator: '',
62
63
  timestamps: true,
@@ -70,6 +71,7 @@ module DbFuel
70
71
  table_name: table_name,
71
72
  attributes: attributes,
72
73
  debug: debug,
74
+ keys_register: keys_register,
73
75
  primary_keyed_column: primary_keyed_column,
74
76
  register: register,
75
77
  separator: separator,
@@ -81,20 +83,16 @@ module DbFuel
81
83
  end
82
84
 
83
85
  def perform(output, payload)
84
- total_rows_affected = 0
85
-
86
86
  payload[register] = array(payload[register])
87
+ keys = resolve_key_set(output, payload)
87
88
 
88
- payload[register].each do |row|
89
- rows_affected = 0
90
-
91
- first_record = update_record(output, row, payload.time)
92
-
93
- rows_affected = 1 if first_record
89
+ total_rows_affected = payload[register].inject(0) do |memo, row|
90
+ first_record = update_record(output, row, payload.time, keys)
91
+ rows_affected = first_record ? 1 : 0
94
92
 
95
93
  debug_detail(output, "Individual Rows Affected: #{rows_affected}")
96
94
 
97
- total_rows_affected += rows_affected
95
+ memo + rows_affected
98
96
  end
99
97
 
100
98
  output.detail("Total Rows Affected: #{total_rows_affected}")
@@ -50,6 +50,7 @@ module DbFuel
50
50
  attributes: [],
51
51
  debug: false,
52
52
  register: Burner::DEFAULT_REGISTER,
53
+ keys_register: nil,
53
54
  separator: '',
54
55
  timestamps: true,
55
56
  unique_attributes: []
@@ -63,6 +64,7 @@ module DbFuel
63
64
  attributes: attributes,
64
65
  debug: debug,
65
66
  primary_keyed_column: nil,
67
+ keys_register: keys_register,
66
68
  register: register,
67
69
  separator: separator,
68
70
  timestamps: timestamps,
@@ -73,19 +75,21 @@ module DbFuel
73
75
  end
74
76
 
75
77
  def perform(output, payload)
76
- total_rows_affected = 0
77
-
78
78
  payload[register] = array(payload[register])
79
+ keys = resolve_key_set(output, payload)
79
80
 
80
- payload[register].each do |row|
81
- where_object = attribute_renderers_set
82
- .transform(unique_attribute_renderers, row, payload.time)
81
+ total_rows_affected = payload[register].inject(0) do |memo, row|
82
+ where_object = attribute_renderers_set.transform(
83
+ unique_attribute_renderers,
84
+ row,
85
+ payload.time
86
+ )
83
87
 
84
- rows_affected = update(output, row, payload.time, where_object)
88
+ rows_affected = update(output, row, payload.time, where_object, keys)
85
89
 
86
90
  debug_detail(output, "Individual Rows Affected: #{rows_affected}")
87
91
 
88
- total_rows_affected += rows_affected
92
+ memo + rows_affected
89
93
  end
90
94
 
91
95
  output.detail("Total Rows Affected: #{total_rows_affected}")
@@ -59,6 +59,7 @@ module DbFuel
59
59
  def initialize(
60
60
  table_name:,
61
61
  primary_keyed_column:,
62
+ keys_register: nil,
62
63
  name: '',
63
64
  attributes: [],
64
65
  debug: false,
@@ -69,6 +70,7 @@ module DbFuel
69
70
  )
70
71
  super(
71
72
  name: name,
73
+ keys_register: keys_register,
72
74
  table_name: table_name,
73
75
  attributes: attributes,
74
76
  debug: debug,
@@ -93,9 +95,10 @@ module DbFuel
93
95
  total_updated = 0
94
96
 
95
97
  payload[register] = array(payload[register])
98
+ keys = resolve_key_set(output, payload)
96
99
 
97
100
  payload[register].each do |row|
98
- record_updated = insert_or_update(output, row, payload.time)
101
+ record_updated = insert_or_update(output, row, payload.time, keys)
99
102
 
100
103
  if record_updated
101
104
  total_updated += 1
@@ -128,7 +131,7 @@ module DbFuel
128
131
  first_record
129
132
  end
130
133
 
131
- def insert_record(output, row, time)
134
+ def insert_record(output, row, time, keys = Set.new)
132
135
  dynamic_attrs = if timestamps
133
136
  # doing an INSERT and timestamps should be set
134
137
  # set the created_at and updated_at fields
@@ -137,7 +140,7 @@ module DbFuel
137
140
  attribute_renderers_set.attribute_renderers
138
141
  end
139
142
 
140
- set_object = attribute_renderers_set.transform(dynamic_attrs, row, time)
143
+ set_object = attribute_renderers_set.transform(dynamic_attrs, row, time, keys)
141
144
 
142
145
  insert_sql = db_provider.insert_sql(set_object)
143
146
 
@@ -152,7 +155,7 @@ module DbFuel
152
155
  end
153
156
 
154
157
  # Updates only a single record. Lookups primary key to update the record.
155
- def update_record(output, row, time)
158
+ def update_record(output, row, time, keys)
156
159
  raise ArgumentError, 'primary_keyed_column is required' unless primary_keyed_column
157
160
 
158
161
  first_record = find_record(output, row, time)
@@ -165,14 +168,14 @@ module DbFuel
165
168
  where_object = { primary_keyed_column.column => id }
166
169
 
167
170
  # update record using the primary key as the WHERE clause
168
- update(output, row, time, where_object)
171
+ update(output, row, time, where_object, keys)
169
172
  end
170
173
 
171
174
  first_record
172
175
  end
173
176
 
174
177
  # Updates one or many records depending on where_object passed
175
- def update(output, row, time, where_object)
178
+ def update(output, row, time, where_object, keys)
176
179
  dynamic_attrs = if timestamps
177
180
  # doing an UPDATE and timestamps should be set,
178
181
  # modify the updated_at field, don't modify the created_at field
@@ -181,7 +184,7 @@ module DbFuel
181
184
  attribute_renderers_set.attribute_renderers
182
185
  end
183
186
 
184
- set_object = attribute_renderers_set.transform(dynamic_attrs, row, time)
187
+ set_object = attribute_renderers_set.transform(dynamic_attrs, row, time, keys)
185
188
 
186
189
  update_sql = db_provider.update_sql(set_object, where_object)
187
190
 
@@ -194,14 +197,14 @@ module DbFuel
194
197
 
195
198
  private
196
199
 
197
- def insert_or_update(output, row, time)
198
- first_record = update_record(output, row, time)
200
+ def insert_or_update(output, row, time, keys)
201
+ first_record = update_record(output, row, time, keys)
199
202
 
200
203
  if first_record
201
204
  first_record
202
205
  else
203
206
  # create the record
204
- insert_record(output, row, time)
207
+ insert_record(output, row, time, keys)
205
208
  nil
206
209
  end
207
210
  end
@@ -52,8 +52,10 @@ module DbFuel
52
52
  .map { |a| Burner::Modeling::AttributeRenderer.new(a, resolver) }
53
53
  end
54
54
 
55
- def transform(attribute_renderers, row, time)
55
+ def transform(attribute_renderers, row, time, keys = Set.new)
56
56
  attribute_renderers.each_with_object({}) do |attribute_renderer, memo|
57
+ next if keys.any? && keys.exclude?(attribute_renderer.key)
58
+
57
59
  value = attribute_renderer.transform(row, time)
58
60
 
59
61
  resolver.set(memo, attribute_renderer.key, value)
@@ -8,5 +8,5 @@
8
8
  #
9
9
 
10
10
  module DbFuel
11
- VERSION = '2.0.1'
11
+ VERSION = '2.1.0'
12
12
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: db_fuel
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Ruggio
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2021-03-18 00:00:00.000000000 Z
12
+ date: 2021-05-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord