activerecord-update 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/lib/activerecord-update/active_record/base.rb +78 -15
- data/lib/activerecord-update/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c2f6991302388163951e76a30a77490613974ad6
|
4
|
+
data.tar.gz: 69c7913ae32b9b2be3ead5c5570fdad080cc425b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 05c28fe52389d585a66a5e4818c8849c5203a1a53db2399468f84c0449d3ffe1412b3e8604df679ef749eebd65d4eea05bbc14e5fba409af5ef42cbd2f049f4a
|
7
|
+
data.tar.gz: c1ff81888f193ac6477339581a97d93de28ed838ff09f43f312ace5718e5ef275a7eaab903b42368bf44734d4f296f2e942d333daed5d403abc54343d08d12cb
|
data/.rubocop.yml
CHANGED
@@ -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
|
-
|
113
|
-
|
114
|
-
|
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
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
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(
|
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
|
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
|
#
|
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.
|
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-
|
11
|
+
date: 2017-02-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|