db_fuel 1.2.1.pre.alpha.2 → 2.2.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: d9598e6e179eea0d1ccf42b840ffe7e4e2f65a96a6ddb29325347fbc5e1505d6
4
- data.tar.gz: aeffe818413543b6d8233eb8df7f7aabad901d0d1d20092dba5ec13be225a596
3
+ metadata.gz: 96e96867b0df819c4a00e446f47fe586d48a12da5798e0743b8895940ff126af
4
+ data.tar.gz: fed359df2f9d2512740e39ad65fd5e6fabed287fb1403bed525fe4b0af5bdf0d
5
5
  SHA512:
6
- metadata.gz: 7a7955d596ed663afb0fea4033bacb0dd21199a4793c7de4f81443a0d1327b613c1fa68bed544f32a411c4947baa41c1d700732afdecdd80b468bd884bc168d4
7
- data.tar.gz: 39731b68e5e748c94d3792e3ac7f567410cfbfd7e3c3946e8de62e6748977af450c1cce41d4f6f1c404446ea885624d2ff4e1abf49d8dd11c638d576492fcb1f
6
+ metadata.gz: 72382d90f1368e9ac9d4cb35a64b60235ec5822568be79ce5a92fd956e41eed9a139d6cf9681585af24932c4e5ff7759e8cb4b36eb2e1cefa0f20e120baa478c
7
+ data.tar.gz: d127c76c1d94e35e2c8b46aff67c6e80735b9381348ae3fb984e983b67701889b0448d5ae00e53218ec52453d7a7e1d7f3df39feaefaaa139652fe35e36fbaff
data/CHANGELOG.md CHANGED
@@ -1,3 +1,30 @@
1
+
2
+ # 2.2.0 (May 23rd, 2021)
3
+
4
+ Updates:
5
+
6
+ * Updating dependencies for dbee to include newest versions.
7
+ # 2.1.0 (May 19th, 2021)
8
+
9
+ Additions:
10
+
11
+ * Added keys_register to all db_fuel/active_record jobs.
12
+
13
+ # 2.0.1 (March 18th, 2021)
14
+
15
+ Changes:
16
+
17
+ * Updated attribute_renderer_set to avoid an evaluation time issue with acts_as_hashable.
18
+
19
+ # 2.0.0 (March 16th, 2021)
20
+
21
+ New Jobs:
22
+ * db_fuel/active_record/upsert
23
+ * db_fuel/active_record/update_all
24
+
25
+ Changes:
26
+ * db_fuel/active_record/update now only updates a single record. Use db_fuel/active_record/update_all to update multiple records at a time.
27
+
1
28
  # 1.1.0 (Decmeber 1st, 2020)
2
29
 
3
30
  New Jobs:
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_key, 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_key, register, separator, timestamps]: This job can take the objects in a register and insert them into a database table. If primary_key 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_key, 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_key is used to update the unique record. Only one record will be updated per statement. Refer to the class and constructor specification for more detail.
31
- * **db_fuel/active_record/upsert** [name, table_name, attributes, debug, primary_key, 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_key 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
 
@@ -187,7 +187,7 @@ pipeline = {
187
187
  { key: :last_name }
188
188
  ],
189
189
  table_name: 'patients',
190
- primary_key: {
190
+ primary_keyed_column: {
191
191
  key: :id
192
192
  }
193
193
  }
@@ -203,13 +203,13 @@ There should now be two new patients, AB0 and AB1, present in the table `patient
203
203
 
204
204
  Notes:
205
205
 
206
- * Since we specified the `primary_key`, the records' `id` attributes should be set to their respective primary key values.
206
+ * Since we specified the `primary_keyed_column`, the records' `id` attributes should be set to their respective primary key values.
207
207
  * Composite primary keys are not currently supported.
208
208
  * Set `debug: true` to print out each INSERT statement in the output (not for production use.)
209
209
 
210
210
  #### Inserting Only New Records
211
211
 
212
- Another job `db_fuel/active_record/find_or_insert` allows for an existence check to performed each insertion. If a record is found then it will not insert the record. If `primary_key` is set then the existence check will also still set the primary key on the payload's respective object. Note that composite primary keys are not currently supported. We can build on the above insert example for only inserting new patients if their chart_number is unique:
212
+ Another job `db_fuel/active_record/find_or_insert` allows for an existence check to performed each insertion. If a record is found then it will not insert the record. If `primary_keyed_column` is set then the existence check will also still set the primary key on the payload's respective object. Note that composite primary keys are not currently supported. We can build on the above insert example for only inserting new patients if their chart_number is unique:
213
213
 
214
214
  ````ruby
215
215
  pipeline = {
@@ -233,7 +233,7 @@ pipeline = {
233
233
  { key: :last_name }
234
234
  ],
235
235
  table_name: 'patients',
236
- primary_key: {
236
+ primary_keyed_column: {
237
237
  key: :id
238
238
  },
239
239
  unique_attributes: [
@@ -274,7 +274,7 @@ pipeline = {
274
274
  { key: :last_name }
275
275
  ],
276
276
  table_name: 'patients',
277
- primary_key: {
277
+ primary_keyed_column: {
278
278
  key: :id
279
279
  },
280
280
  unique_attributes: [
@@ -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
@@ -356,7 +356,7 @@ pipeline = {
356
356
  { key: :last_name }
357
357
  ],
358
358
  table_name: 'patients',
359
- primary_key: {
359
+ primary_keyed_column: {
360
360
  key: :id
361
361
  },
362
362
  unique_attributes: [
@@ -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
data/db_fuel.gemspec CHANGED
@@ -43,8 +43,8 @@ Gem::Specification.new do |s|
43
43
  s.add_dependency('activerecord', activerecord_version)
44
44
  s.add_dependency('acts_as_hashable', '~>1.2')
45
45
  s.add_dependency('burner', '~>1.7')
46
- s.add_dependency('dbee', '~>2.1')
47
- s.add_dependency('dbee-active_record', '~>2.1')
46
+ s.add_dependency('dbee', '~>3.0')
47
+ s.add_dependency('dbee-active_record', '~>2.2')
48
48
  s.add_dependency('objectable', '~>1.0')
49
49
 
50
50
  s.add_development_dependency('guard-rspec', '~>4.7')
@@ -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,14 +31,16 @@ 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)
39
- @attribute_renderers_set = Modeling::AttributeRendererSet.new(attributes: attributes,
40
- resolver: resolver)
40
+ @keys_register = keys_register.to_s
41
+ @resolver = Objectable.resolver(separator: separator)
42
+ @attribute_renderers_set = Modeling::AttributeRendererSet.new(resolver: resolver,
43
+ attributes: attributes)
41
44
  @db_provider = DbProvider.new(table_name)
42
45
  @debug = debug || false
43
46
  end
@@ -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
@@ -14,8 +14,9 @@ module DbFuel
14
14
  module ActiveRecord
15
15
  # This job is a slight enhancement to the insert job, in that it will only insert new
16
16
  # records. It will use the unique_keys to first run a query to see if it exists.
17
- # Each unique_key becomes a WHERE clause. If primary_key is specified and a record is
18
- # found then the first record's id will be set to the primary_key.
17
+ # Each unique_key becomes a WHERE clause. If primary_keyed_column is specified
18
+ # and a record is found then the first record's id will be set to
19
+ # the primary_keyed_column.
19
20
  #
20
21
  # Expected Payload[register] input: array of objects
21
22
  # Payload[register] output: array of objects.
@@ -36,8 +37,9 @@ module DbFuel
36
37
  # returned objects will be printed in the output. Only use this option while
37
38
  # debugging issues as it will fill up the output with (potentially too much) data.
38
39
  #
39
- # primary_key: If primary_key is present then it will be used to set the object's
40
- # property to the returned primary key from the INSERT statement.
40
+ # primary_keyed_column: If primary_keyed_column is present then it will be used to set
41
+ # the object's property to the returned primary key
42
+ # from the INSERT statement.
41
43
  #
42
44
  # separator: Just like other jobs with a 'separator' option, if the objects require
43
45
  # key-path notation or nested object support, you can set the separator
@@ -55,7 +57,8 @@ module DbFuel
55
57
  name: '',
56
58
  attributes: [],
57
59
  debug: false,
58
- primary_key: nil,
60
+ keys_register: nil,
61
+ primary_keyed_column: nil,
59
62
  register: Burner::DEFAULT_REGISTER,
60
63
  separator: '',
61
64
  timestamps: true,
@@ -64,10 +67,11 @@ module DbFuel
64
67
 
65
68
  super(
66
69
  name: name,
70
+ keys_register: keys_register,
67
71
  table_name: table_name,
68
72
  attributes: attributes,
69
73
  debug: debug,
70
- primary_key: primary_key,
74
+ primary_keyed_column: primary_keyed_column,
71
75
  register: register,
72
76
  separator: separator,
73
77
  timestamps: timestamps,
@@ -80,6 +84,7 @@ module DbFuel
80
84
  total_existed = 0
81
85
 
82
86
  payload[register] = array(payload[register])
87
+ keys = resolve_key_set(output, payload)
83
88
 
84
89
  payload[register].each do |row|
85
90
  exists = find_record(output, row, payload.time)
@@ -89,7 +94,7 @@ module DbFuel
89
94
  next
90
95
  end
91
96
 
92
- insert_record(output, row, payload.time)
97
+ insert_record(output, row, payload.time, keys)
93
98
 
94
99
  total_inserted += 1
95
100
  end
@@ -17,8 +17,6 @@ module DbFuel
17
17
  # Expected Payload[register] input: array of objects
18
18
  # Payload[register] output: array of objects.
19
19
  class Insert < Upsert
20
- # attr_reader :primary_key
21
-
22
20
  # Arguments:
23
21
  # name: name of the job within the Burner::Pipeline.
24
22
  #
@@ -33,8 +31,9 @@ module DbFuel
33
31
  # returned objects will be printed in the output. Only use this option while
34
32
  # debugging issues as it will fill up the output with (potentially too much) data.
35
33
  #
36
- # primary_key: If primary_key is present then it will be used to set the object's
37
- # property to the returned primary key from the INSERT statement.
34
+ # primary_keyed_column: If primary_keyed_column is present then it will be used to
35
+ # set the object's property to the returned primary key
36
+ # from the INSERT statement.
38
37
  #
39
38
  # separator: Just like other jobs with a 'separator' option, if the objects require
40
39
  # key-path notation or nested object support, you can set the separator
@@ -46,23 +45,24 @@ module DbFuel
46
45
  # to the current UTC timestamp.
47
46
  def initialize(
48
47
  table_name:,
48
+ keys_register: nil,
49
49
  name: '',
50
50
  attributes: [],
51
51
  debug: false,
52
- primary_key: nil,
52
+ primary_keyed_column: nil,
53
53
  register: Burner::DEFAULT_REGISTER,
54
54
  separator: '',
55
55
  timestamps: true
56
56
  )
57
-
58
57
  attributes = Burner::Modeling::Attribute.array(attributes)
59
58
 
60
59
  super(
61
60
  name: name,
61
+ keys_register: keys_register,
62
62
  table_name: table_name,
63
63
  attributes: attributes,
64
64
  debug: debug,
65
- primary_key: primary_key,
65
+ primary_keyed_column: primary_keyed_column,
66
66
  register: register,
67
67
  separator: separator,
68
68
  timestamps: timestamps
@@ -71,8 +71,11 @@ module DbFuel
71
71
 
72
72
  def perform(output, payload)
73
73
  payload[register] = array(payload[register])
74
+ keys = resolve_key_set(output, payload)
75
+
76
+ output.detail("Inserting #{payload[register].count} record(s)")
74
77
 
75
- payload[register].each { |row| insert_record(output, row, payload.time) }
78
+ payload[register].each { |row| insert_record(output, row, payload.time, keys) }
76
79
  end
77
80
  end
78
81
  end
@@ -15,7 +15,7 @@ module DbFuel
15
15
  # This job can take the unique objects in a register and updates them within database table.
16
16
  # The attributes translate to SQL SET clauses and the unique_keys translate to
17
17
  # WHERE clauses to find the records to update.
18
- # The primary_key is used to update the unique record.
18
+ # The primary_keyed_column is used to update the unique record.
19
19
  # Only one record will be updated per statement.
20
20
  #
21
21
  # Expected Payload[register] input: array of objects
@@ -35,7 +35,7 @@ module DbFuel
35
35
  # returned objects will be printed in the output. Only use this option while
36
36
  # debugging issues as it will fill up the output with (potentially too much) data.
37
37
  #
38
- # primary_key [required]: Primary key column for the corresponding table.
38
+ # primary_keyed_column [required]: Primary key column for the corresponding table.
39
39
  # Used as the WHERE clause for the UPDATE statement.
40
40
  # Only one record will be updated at a time
41
41
  # using the primary key specified.
@@ -56,7 +56,8 @@ module DbFuel
56
56
  name: '',
57
57
  attributes: [],
58
58
  debug: false,
59
- primary_key: nil,
59
+ primary_keyed_column: nil,
60
+ keys_register: nil,
60
61
  register: Burner::DEFAULT_REGISTER,
61
62
  separator: '',
62
63
  timestamps: true,
@@ -70,7 +71,8 @@ module DbFuel
70
71
  table_name: table_name,
71
72
  attributes: attributes,
72
73
  debug: debug,
73
- primary_key: primary_key,
74
+ keys_register: keys_register,
75
+ primary_keyed_column: primary_keyed_column,
74
76
  register: register,
75
77
  separator: separator,
76
78
  timestamps: timestamps,
@@ -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: []
@@ -62,7 +63,8 @@ module DbFuel
62
63
  table_name: table_name,
63
64
  attributes: attributes,
64
65
  debug: debug,
65
- primary_key: nil,
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}")
@@ -16,12 +16,12 @@ module DbFuel
16
16
  # It will use the unique_keys to first run a query to see if it exists.
17
17
  # Each unique_key becomes a WHERE clause. If a record is found it will then
18
18
  # update the found record using the primary key specified.
19
- # If a record is updated or created the record's id will be set to the primary_key.
19
+ # If a record is updated or created the record's id will be set to the primary_keyed_column.
20
20
  #
21
21
  # Expected Payload[register] input: array of objects
22
22
  # Payload[register] output: array of objects.
23
23
  class Upsert < Base
24
- attr_reader :primary_key, :timestamps, :unique_attribute_renderers
24
+ attr_reader :primary_keyed_column, :timestamps, :unique_attribute_renderers
25
25
 
26
26
  # Arguments:
27
27
  # name: name of the job within the Burner::Pipeline.
@@ -38,9 +38,10 @@ module DbFuel
38
38
  # debugging issues as it will fill
39
39
  # up the output with (potentially too much) data.
40
40
  #
41
- # primary_key [required]: Used to set the object's property to the returned primary key
42
- # from the INSERT statement or used as the
43
- # WHERE clause for the UPDATE statement.
41
+ # primary_keyed_column [required]: Used to set the object's property to the
42
+ # returned primary key from the
43
+ # INSERT statement or used as the
44
+ # WHERE clause for the UPDATE statement.
44
45
  #
45
46
  # separator: Just like other jobs with a 'separator' option, if the objects require
46
47
  # key-path notation or nested object support, you can set the separator
@@ -57,7 +58,8 @@ module DbFuel
57
58
  # order to check for the existence of a specific record.
58
59
  def initialize(
59
60
  table_name:,
60
- primary_key:,
61
+ primary_keyed_column:,
62
+ keys_register: nil,
61
63
  name: '',
62
64
  attributes: [],
63
65
  debug: false,
@@ -68,6 +70,7 @@ module DbFuel
68
70
  )
69
71
  super(
70
72
  name: name,
73
+ keys_register: keys_register,
71
74
  table_name: table_name,
72
75
  attributes: attributes,
73
76
  debug: debug,
@@ -75,10 +78,10 @@ module DbFuel
75
78
  separator: separator
76
79
  )
77
80
 
78
- @primary_key = Modeling::KeyedColumn.make(primary_key, nullable: true)
81
+ @primary_keyed_column = Modeling::KeyedColumn.make(primary_keyed_column, nullable: true)
79
82
 
80
83
  @unique_attribute_renderers = attribute_renderers_set
81
- .make_attribute_renderers(unique_attributes)
84
+ .make_renderers(unique_attributes)
82
85
 
83
86
  @timestamps = timestamps
84
87
 
@@ -86,15 +89,16 @@ module DbFuel
86
89
  end
87
90
 
88
91
  def perform(output, payload)
89
- raise ArgumentError, 'primary_key is required' unless primary_key
92
+ raise ArgumentError, 'primary_keyed_column is required' unless primary_keyed_column
90
93
 
91
94
  total_inserted = 0
92
95
  total_updated = 0
93
96
 
94
97
  payload[register] = array(payload[register])
98
+ keys = resolve_key_set(output, payload)
95
99
 
96
100
  payload[register].each do |row|
97
- record_updated = insert_or_update(output, row, payload.time)
101
+ record_updated = insert_or_update(output, row, payload.time, keys)
98
102
 
99
103
  if record_updated
100
104
  total_updated += 1
@@ -118,16 +122,16 @@ module DbFuel
118
122
 
119
123
  first_record = db_provider.first(unique_row)
120
124
 
121
- id = resolver.get(first_record, primary_key.column)
125
+ id = resolver.get(first_record, primary_keyed_column.column)
122
126
 
123
- resolver.set(row, primary_key.key, id)
127
+ resolver.set(row, primary_keyed_column.key, id)
124
128
 
125
129
  debug_detail(output, "Record Exists: #{first_record}") if first_record
126
130
 
127
131
  first_record
128
132
  end
129
133
 
130
- def insert_record(output, row, time)
134
+ def insert_record(output, row, time, keys = Set.new)
131
135
  dynamic_attrs = if timestamps
132
136
  # doing an INSERT and timestamps should be set
133
137
  # set the created_at and updated_at fields
@@ -136,7 +140,7 @@ module DbFuel
136
140
  attribute_renderers_set.attribute_renderers
137
141
  end
138
142
 
139
- set_object = attribute_renderers_set.transform(dynamic_attrs, row, time)
143
+ set_object = attribute_renderers_set.transform(dynamic_attrs, row, time, keys)
140
144
 
141
145
  insert_sql = db_provider.insert_sql(set_object)
142
146
 
@@ -144,34 +148,34 @@ module DbFuel
144
148
 
145
149
  id = db_provider.insert(set_object)
146
150
 
147
- # add the primary key name and value to row if primary_key was specified
148
- resolver.set(row, primary_key.key, id) if primary_key
151
+ # add the primary key name and value to row if primary_keyed_column was specified
152
+ resolver.set(row, primary_keyed_column.key, id) if primary_keyed_column
149
153
 
150
154
  debug_detail(output, "Insert Return: #{row}")
151
155
  end
152
156
 
153
157
  # Updates only a single record. Lookups primary key to update the record.
154
- def update_record(output, row, time)
155
- raise ArgumentError, 'primary_key is required' unless primary_key
158
+ def update_record(output, row, time, keys)
159
+ raise ArgumentError, 'primary_keyed_column is required' unless primary_keyed_column
156
160
 
157
161
  first_record = find_record(output, row, time)
158
162
 
159
163
  if first_record
160
164
  debug_detail(output, "Record Exists: #{first_record}")
161
165
 
162
- id = resolver.get(first_record, primary_key.column)
166
+ id = resolver.get(first_record, primary_keyed_column.column)
163
167
 
164
- where_object = { primary_key.key => id }
168
+ where_object = { primary_keyed_column.column => id }
165
169
 
166
170
  # update record using the primary key as the WHERE clause
167
- update(output, row, time, where_object)
171
+ update(output, row, time, where_object, keys)
168
172
  end
169
173
 
170
174
  first_record
171
175
  end
172
176
 
173
177
  # Updates one or many records depending on where_object passed
174
- def update(output, row, time, where_object)
178
+ def update(output, row, time, where_object, keys)
175
179
  dynamic_attrs = if timestamps
176
180
  # doing an UPDATE and timestamps should be set,
177
181
  # modify the updated_at field, don't modify the created_at field
@@ -180,7 +184,7 @@ module DbFuel
180
184
  attribute_renderers_set.attribute_renderers
181
185
  end
182
186
 
183
- set_object = attribute_renderers_set.transform(dynamic_attrs, row, time)
187
+ set_object = attribute_renderers_set.transform(dynamic_attrs, row, time, keys)
184
188
 
185
189
  update_sql = db_provider.update_sql(set_object, where_object)
186
190
 
@@ -193,14 +197,14 @@ module DbFuel
193
197
 
194
198
  private
195
199
 
196
- def insert_or_update(output, row, time)
197
- 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)
198
202
 
199
203
  if first_record
200
204
  first_record
201
205
  else
202
206
  # create the record
203
- insert_record(output, row, time)
207
+ insert_record(output, row, time, keys)
204
208
  nil
205
209
  end
206
210
  end
@@ -12,18 +12,18 @@ module DbFuel
12
12
  # Creates attribute renderers based on attributes passed.
13
13
  # Also constains methods to transform attribute renderers
14
14
  # and include timestamp attributes if needed.
15
- class AttributeRendererSet
16
- CREATED_AT = :created_at
15
+ class AttributeRendererSet # :nodoc:
17
16
  NOW_TYPE = 'r/value/now'
17
+ CREATED_AT = :created_at
18
18
  UPDATED_AT = :updated_at
19
19
 
20
20
  attr_reader :attribute_renderers, :resolver
21
21
 
22
- def initialize(attributes: [], resolver: nil)
22
+ def initialize(resolver:, attributes: [])
23
23
  raise ArgumentError, 'resolver is required' unless resolver
24
24
 
25
25
  @resolver = resolver
26
- @attribute_renderers = make_attribute_renderers(attributes)
26
+ @attribute_renderers = make_renderers(attributes)
27
27
 
28
28
  freeze
29
29
  end
@@ -46,22 +46,22 @@ module DbFuel
46
46
  end + attribute_renderers
47
47
  end
48
48
 
49
- def make_attribute_renderers(attributes)
49
+ def make_renderers(attributes)
50
50
  Burner::Modeling::Attribute
51
51
  .array(attributes)
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)
60
62
  end
61
63
  end
62
64
 
63
- private
64
-
65
65
  def created_at_timestamp_attribute
66
66
  timestamp_attribute(CREATED_AT)
67
67
  end
@@ -8,5 +8,5 @@
8
8
  #
9
9
 
10
10
  module DbFuel
11
- VERSION = '1.2.1-alpha.2'
11
+ VERSION = '2.2.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: 1.2.1.pre.alpha.2
4
+ version: 2.2.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-01-25 00:00:00.000000000 Z
12
+ date: 2021-05-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -65,28 +65,28 @@ dependencies:
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '2.1'
68
+ version: '3.0'
69
69
  type: :runtime
70
70
  prerelease: false
71
71
  version_requirements: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '2.1'
75
+ version: '3.0'
76
76
  - !ruby/object:Gem::Dependency
77
77
  name: dbee-active_record
78
78
  requirement: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '2.1'
82
+ version: '2.2'
83
83
  type: :runtime
84
84
  prerelease: false
85
85
  version_requirements: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '2.1'
89
+ version: '2.2'
90
90
  - !ruby/object:Gem::Dependency
91
91
  name: objectable
92
92
  requirement: !ruby/object:Gem::Requirement
@@ -274,9 +274,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
274
274
  version: '2.5'
275
275
  required_rubygems_version: !ruby/object:Gem::Requirement
276
276
  requirements:
277
- - - ">"
277
+ - - ">="
278
278
  - !ruby/object:Gem::Version
279
- version: 1.3.1
279
+ version: '0'
280
280
  requirements: []
281
281
  rubygems_version: 3.0.3
282
282
  signing_key: