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

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: 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