activerecord-batch_touching 1.0.pre.beta3 → 1.0.pre.beta4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c3c3f592e6fe0beb099dd3d0cec1d0bbc02fe79ef20acc193169bcbf89082aee
4
- data.tar.gz: c6f278bb704653d5cc21ff088c80623c53c69abce995694bfe5e37b9bfccb4fe
3
+ metadata.gz: 8e3ae09116c725e745e467afa1d834b6b2a28bcae4f01d5346e598235bb7d0a8
4
+ data.tar.gz: 842acced5ccc6df3149f4ae60b2b7f574f1bf04a553a67b54d6832c1501b94ee
5
5
  SHA512:
6
- metadata.gz: 2fb2776ed67057081efd3103932e6f740d39a6c55f5840b1bcc184aab845e1ce08fbd68e9824bc911ea0c41b1df830d6f9a4f014deadd7c49691f5b72a314ad5
7
- data.tar.gz: 34d7055a78683221bfe8883ee0deb9643a973bf005ff2c3c1987abd65e11489c6306079ec17e1ede9384194c6fd709a598c2ad6434d33b982a786f917e51cbfd
6
+ metadata.gz: 5339c3f783b5b4e8f667a47437fa26e507353d648fd99f637ea73925c28d07d626c7eeb9a8850552ae4182ebb1d36ae9acb5acbe0e2d42e7b0d9f1664a0d86d7
7
+ data.tar.gz: bf5025309b66d19d7571ef34a3701eb23d9d8c054b68619bb6ad1f881439b37eb99e2a6fdd67e53dbadccf585ea41ae2703ee09fe10d3a81dd9e422675aa8b56
@@ -55,6 +55,28 @@ module ActiveRecord
55
55
  end
56
56
 
57
57
  class << self
58
+ # Disable batch touching globally
59
+ def disable!
60
+ @disabled = true
61
+ end
62
+
63
+ # Enable batch touching globally
64
+ def enable!
65
+ @disabled = false
66
+ end
67
+
68
+ # Disable batch touching for a block
69
+ def disable
70
+ Thread.current[:batch_touching_disabled] = false
71
+ yield
72
+ ensure
73
+ Thread.current[:batch_touching_disabled] = false
74
+ end
75
+
76
+ def disabled?
77
+ Thread.current[:batch_touching_disabled] || @disabled
78
+ end
79
+
58
80
  def states
59
81
  Thread.current[:batch_touching_states] ||= []
60
82
  end
@@ -66,7 +88,7 @@ module ActiveRecord
66
88
  delegate :add_record, to: :current_state
67
89
 
68
90
  def batch_touching?
69
- states.present?
91
+ states.present? && !disabled?
70
92
  end
71
93
 
72
94
  # Start batching all touches. When done, apply them. (Unless nested.)
@@ -91,20 +113,15 @@ module ActiveRecord
91
113
 
92
114
  # Apply the touches that were batched. We're in a transaction already so there's no need to open one.
93
115
  def apply_touches
116
+ current_time = ActiveRecord::Base.current_time_from_proper_timezone
94
117
  callbacks_run = Set.new
95
118
  all_states = State.new
96
119
  while current_state.more_records?
97
120
  all_states.merge!(current_state)
98
121
  state_records = current_state.records
99
122
  current_state.clear_records!
100
- state_records.each do |_, records|
101
- # Run callbacks to collect more touches (i.e. touch: true for associations)
102
- records.each do |record|
103
- unless callbacks_run.include?(record)
104
- record._run_touch_callbacks
105
- callbacks_run.add(record)
106
- end
107
- end
123
+ state_records.each do |(_klass, columns), records|
124
+ soft_touch_records(columns, records, current_time, callbacks_run)
108
125
  end
109
126
  end
110
127
 
@@ -112,30 +129,38 @@ module ActiveRecord
112
129
  sorted_records = all_states.records.keys.sort_by { |k| k.first.name }.map { |k| [k, all_states.records[k]] }.to_h
113
130
  sorted_records.each do |(klass, columns), records|
114
131
  records.reject!(&:destroyed?)
115
- touch_records klass, columns, records if records.present?
132
+ touch_records klass, columns, records, current_time if records.present?
116
133
  end
117
134
  end
118
135
 
119
- # Touch the specified records--non-empty set of instances of the same class.
120
- def touch_records(klass, columns, records)
121
- if columns.present?
122
- current_time = records.first.send(:current_time_from_proper_timezone)
123
-
124
- records.each do |record|
125
- record.instance_eval do
126
- columns.each { |column| write_attribute column, current_time }
136
+ # Only set new timestamp in memory.
137
+ # Running callbacks also allows us to collect more touches (i.e. touch: true for associations).
138
+ def soft_touch_records(columns, records, time, callbacks_run)
139
+ records.each do |record|
140
+ record.instance_eval do
141
+ unless destroyed?
142
+ columns.each { |column| write_attribute column, time }
127
143
  if locking_enabled?
128
144
  self[self.class.locking_column] += 1
129
145
  clear_attribute_change(self.class.locking_column)
130
146
  end
131
147
  clear_attribute_changes(columns)
132
148
  end
149
+ unless callbacks_run.include?(record)
150
+ record._run_touch_callbacks
151
+ callbacks_run.add(record)
152
+ end
133
153
  end
154
+ end
155
+ end
134
156
 
135
- sql = columns.map { |column| "#{klass.connection.quote_column_name(column)} = :current_time" }.join(", ")
157
+ # Touch the specified records--non-empty set of instances of the same class.
158
+ def touch_records(klass, columns, records, time)
159
+ if columns.present?
160
+ sql = columns.map { |column| "#{klass.connection.quote_column_name(column)} = :time" }.join(", ")
136
161
  sql += ", #{klass.locking_column} = #{klass.locking_column} + 1" if klass.locking_enabled?
137
162
 
138
- klass.unscoped.where(klass.primary_key => records.to_a).update_all([sql, current_time: current_time])
163
+ klass.unscoped.where(klass.primary_key => records.to_a).update_all([sql, time: time])
139
164
  end
140
165
  end
141
166
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-batch_touching
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.pre.beta3
4
+ version: 1.0.pre.beta4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Morearty