activerecord-update 0.0.1 → 0.0.2

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
  SHA1:
3
- metadata.gz: ea8267a673e2b98e469272b396c95715d72293a0
4
- data.tar.gz: 758e3c003b4711eb333f99dc89488a9f84dbf6e0
3
+ metadata.gz: c2f6991302388163951e76a30a77490613974ad6
4
+ data.tar.gz: 69c7913ae32b9b2be3ead5c5570fdad080cc425b
5
5
  SHA512:
6
- metadata.gz: 6bd413d5d665399e192852db292c1624ea7d6b5e95ab86bc4956aeb5ad56a1aec83f3c1ecb6c4920f1628fdb07892ddbf39e68d46d571bb92552f01fc427bf2a
7
- data.tar.gz: 65ffd2ccf31fab618f5cf5e316691321cbeebdaf33a785a495c1db51f3b2a75658c95a9f5d16092c3b4b141bdc4d958a036897b45461172b34cf8a48f1092184
6
+ metadata.gz: 05c28fe52389d585a66a5e4818c8849c5203a1a53db2399468f84c0449d3ffe1412b3e8604df679ef749eebd65d4eea05bbc14e5fba409af5ef42cbd2f049f4a
7
+ data.tar.gz: c1ff81888f193ac6477339581a97d93de28ed838ff09f43f312ace5718e5ef275a7eaab903b42368bf44734d4f296f2e942d333daed5d403abc54343d08d12cb
@@ -14,3 +14,6 @@ Metrics/BlockLength:
14
14
  Exclude:
15
15
  - activerecord-update.gemspec
16
16
  - spec/**/*_spec.rb
17
+
18
+ Style/AlignParameters:
19
+ EnforcedStyle: with_fixed_indentation
@@ -98,6 +98,7 @@ module ActiveRecord
98
98
  private
99
99
 
100
100
  # rubocop:disable Metrics/MethodLength
101
+ # rubocop:disable Metrics/AbcSize
101
102
 
102
103
  # (see .update_records)
103
104
  #
@@ -109,9 +110,9 @@ module ActiveRecord
109
110
  #
110
111
  # @see .update_records
111
112
  def _update_records(
112
- records,
113
- raise_on_validation_failure:,
114
- raise_on_stale_objects:
113
+ records,
114
+ raise_on_validation_failure:,
115
+ raise_on_stale_objects:
115
116
  )
116
117
 
117
118
  changed = changed_records(records)
@@ -119,15 +120,28 @@ module ActiveRecord
119
120
  return build_result(valid, failed, []) if valid.empty?
120
121
 
121
122
  timestamp = current_time
122
- query = sql_for_update_records(valid, timestamp)
123
- ids = perform_update_records_query(query, primary_key)
124
- result = build_result(valid, failed, ids)
125
- validate_result(result, raise_on_stale_objects)
126
-
127
- update_timestamp(valid, timestamp)
128
- mark_changes_applied(valid)
129
- result
123
+ previous_lock_values = {}
124
+
125
+ begin
126
+ query = sql_for_update_records(valid, timestamp, previous_lock_values)
127
+ ids = perform_update_records_query(query, primary_key)
128
+ result = build_result(valid, failed, ids)
129
+ restore_lock(result.stale_objects, previous_lock_values)
130
+
131
+ successful_records = valid - result.stale_objects
132
+ update_timestamp(successful_records, timestamp)
133
+ mark_changes_applied(successful_records)
134
+
135
+ validate_result(result, raise_on_stale_objects)
136
+ result
137
+ # rubocop:disable Lint/RescueException
138
+ rescue Exception
139
+ # rubocop:enable Lint/RescueException
140
+ restore_lock(records, previous_lock_values)
141
+ raise
142
+ end
130
143
  end
144
+ # rubocop:enable Metrics/AbcSize
131
145
  # rubocop:enable Metrics/MethodLength
132
146
 
133
147
  # Returns the given records that are not new records and have changed.
@@ -210,12 +224,17 @@ module ActiveRecord
210
224
  # @param records [<ActiveRecord::Base>] the records that have changed
211
225
  # @param timestamp [Time] the timestamp used for the `updated_at` column
212
226
  #
227
+ # @param previous_lock_values [{ Integer => Integer }] on return, this
228
+ # hash will contain the record ID's mapping to the previous lock
229
+ # versions. In an error occurs this hash can be used to restore the lock
230
+ # attribute to its previous value.
231
+ #
213
232
  # @return the SQL query for the #{update_records} method
214
233
  #
215
234
  # @see #update_records
216
235
  # rubocop:disable Metrics/MethodLength
217
236
  # rubocop:disable Metrics/AbcSize
218
- def sql_for_update_records(records, timestamp)
237
+ def sql_for_update_records(records, timestamp, previous_lock_values)
219
238
  attributes = changed_attributes(records)
220
239
  quoted_changed_attributes = changed_attributes_for_sql(
221
240
  attributes, quoted_table_alias
@@ -223,7 +242,12 @@ module ActiveRecord
223
242
 
224
243
  attributes = all_attributes(attributes)
225
244
  casts = type_casts(attributes)
226
- values = changed_values(records, attributes, timestamp)
245
+ values = changed_values(
246
+ records,
247
+ attributes,
248
+ timestamp,
249
+ previous_lock_values
250
+ )
227
251
  quoted_values = values_for_sql(values)
228
252
  quoted_column_names = column_names_for_sql(attributes)
229
253
  template = build_sql_template
@@ -353,6 +377,7 @@ module ActiveRecord
353
377
  end
354
378
 
355
379
  # rubocop:disable Metrics/MethodLength
380
+ # rubocop:disable Metrics/AbcSize
356
381
 
357
382
  # Returns the values of the given records that have changed.
358
383
  #
@@ -390,11 +415,18 @@ module ActiveRecord
390
415
  #
391
416
  # @param updated_at [Time] the value of the updated_at column
392
417
  #
418
+ # @param previous_lock_values [{ Integer => Integer }] on return, this
419
+ # hash will contain the record ID's mapping to the previous lock
420
+ # versions. In an error occurs this hash can be used to restore the lock
421
+ # attribute to its previous value.
422
+ #
393
423
  # @return [<<Object>>] the changed values
394
424
  #
395
425
  # @raise [ArgumentError]
396
426
  # * if the given list of records or changed attributes is `nil` or empty
397
- def changed_values(records, changed_attributes, updated_at)
427
+ def changed_values(records, changed_attributes, updated_at,
428
+ previous_lock_values)
429
+
398
430
  raise ArgumentError, 'No changed records given' if records.blank?
399
431
 
400
432
  if changed_attributes.blank?
@@ -404,6 +436,10 @@ module ActiveRecord
404
436
  extract_changed_values = lambda do |record|
405
437
  previous_lock_value = increment_lock(record)
406
438
 
439
+ if locking_enabled?
440
+ previous_lock_values[record.id] = previous_lock_value
441
+ end
442
+
407
443
  # We're using `slice` instead of `changed_attributes` because we need
408
444
  # to include all the changed attributes from all the changed records
409
445
  # and not just the changed attributes for a given record.
@@ -417,11 +453,17 @@ module ActiveRecord
417
453
 
418
454
  records.map(&extract_changed_values)
419
455
  end
456
+ # rubocop:enable Metrics/AbcSize
420
457
  # rubocop:enable Metrics/MethodLength
421
458
 
422
459
  # Increments the lock column of the given record if locking is enabled.
423
460
  #
424
- # @param [ActiveRecord::Base] the record to update the lock column for
461
+ # @param record [ActiveRecord::Base] the record to update the lock column
462
+ # for
463
+ #
464
+ # @param operation [:decrement, :increment] the operation to perform,
465
+ # increment or decrement
466
+ #
425
467
  # @return [void]
426
468
  def increment_lock(record)
427
469
  return unless locking_enabled?
@@ -432,6 +474,27 @@ module ActiveRecord
432
474
  previous_lock_value
433
475
  end
434
476
 
477
+ # Restores the lock column of the given records to given values,
478
+ # if locking is enabled.
479
+ #
480
+ # @param records [<ActiveRecord::Base>] the records to restore the lock
481
+ # column on
482
+ #
483
+ # @param lock_values [{ Integer => Integer }] this hash contains the
484
+ # record ID's mapping to the lock values that should be restored.
485
+ #
486
+ # @return [void]
487
+ def restore_lock(records, lock_values)
488
+ return if !locking_enabled? || records.empty?
489
+ method_name = locking_column + '='
490
+
491
+ records.each do |record|
492
+ lock_value = lock_values[record.id]
493
+ next unless lock_value
494
+ record.send(method_name, lock_value)
495
+ end
496
+ end
497
+
435
498
  # Returns the values of the given records that have changed, formatted for
436
499
  # SQL.
437
500
  #
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module Update
3
- VERSION = '0.0.1'.freeze
3
+ VERSION = '0.0.2'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-update
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jacob Carlborg
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-01-26 00:00:00.000000000 Z
11
+ date: 2017-02-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord