Module: Switchman::ActiveRecord::Base
- Defined in:
- lib/switchman/active_record/base.rb
Defined Under Namespace
Modules: ClassMethods, InitializeShard
Class Method Summary
collapse
Instance Method Summary
collapse
Class Method Details
.prepended(klass) ⇒ Object
Instance Method Details
#canonical? ⇒ Boolean
177
178
179
|
# File 'lib/switchman/active_record/base.rb', line 177
def canonical?
!shadow_record?
end
|
#clone ⇒ Object
256
257
258
259
260
261
262
263
|
# File 'lib/switchman/active_record/base.rb', line 256
def clone
result = super
result.instance_variable_set(:@shard, shard)
result
end
|
#destroy ⇒ Object
252
253
254
|
# File 'lib/switchman/active_record/base.rb', line 252
def destroy
shard.activate(self.class.connection_class_for_self) { super }
end
|
#destroy_shadow_records(target_shards: [Shard.current]) ⇒ Object
197
198
199
200
201
202
203
204
205
206
207
208
209
210
|
# File 'lib/switchman/active_record/base.rb', line 197
def destroy_shadow_records(target_shards: [Shard.current])
raise Errors::ShadowRecordError, "Cannot be called on a shadow record." if shadow_record?
unless self.class.sharded_column?(self.class.primary_key)
raise Errors::MethodUnsupportedForUnshardedTableError,
"Cannot be called on a record belonging to an unsharded table."
end
Array(target_shards).each do |target_shard|
next if target_shard == shard
target_shard.activate { self.class.where("id = ?", global_id).delete_all }
end
end
|
#hash ⇒ Object
278
279
280
|
# File 'lib/switchman/active_record/base.rb', line 278
def hash
self.class.sharded_primary_key? ? [self.class, global_id].hash : super
end
|
#id_for_database ⇒ Object
298
299
300
301
302
303
304
305
306
307
308
|
# File 'lib/switchman/active_record/base.rb', line 298
def id_for_database
if self.class.sharded_primary_key?
id
else
super
end
end
|
#initialize_dup(*args) ⇒ Object
287
288
289
290
291
|
# File 'lib/switchman/active_record/base.rb', line 287
def initialize_dup(*args)
copy = super
@shard_set_in_stone = false
copy
end
|
#loaded_from_shard ⇒ Object
Returns "the shard that this record was actually loaded from" , as
opposed to "the shard this record belongs on", which might be
different if this is a shadow record.
215
216
217
|
# File 'lib/switchman/active_record/base.rb', line 215
def loaded_from_shard
@loaded_from_shard || shard
end
|
#readonly! ⇒ Object
165
166
167
168
|
# File 'lib/switchman/active_record/base.rb', line 165
def readonly!
@readonly_from_shadow = false
super
end
|
#save ⇒ Object
238
239
240
241
242
243
|
# File 'lib/switchman/active_record/base.rb', line 238
def save(*, **)
raise Errors::ManuallyCreatedShadowRecordError if creating_shadow_record?
@shard_set_in_stone = true
super
end
|
#save! ⇒ Object
245
246
247
248
249
250
|
# File 'lib/switchman/active_record/base.rb', line 245
def save!(*, **)
raise Errors::ManuallyCreatedShadowRecordError if creating_shadow_record?
@shard_set_in_stone = true
super
end
|
#save_shadow_record(new_attrs: attributes, target_shard: Shard.current) ⇒ Object
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
|
# File 'lib/switchman/active_record/base.rb', line 181
def save_shadow_record(new_attrs: attributes, target_shard: Shard.current)
return if target_shard == shard
shadow_attrs = {}
new_attrs.each do |attr, value|
shadow_attrs[attr] = if self.class.sharded_column?(attr)
Shard.relative_id_for(value, shard, target_shard)
else
value
end
end
target_shard.activate do
self.class.upsert_all([shadow_attrs], unique_by: self.class.primary_key)
end
end
|
#shadow_record? ⇒ Boolean
170
171
172
173
174
175
|
# File 'lib/switchman/active_record/base.rb', line 170
def shadow_record?
pkey = self[self.class.primary_key]
return false unless self.class.sharded_column?(self.class.primary_key) && pkey
pkey > Shard::IDS_PER_SHARD
end
|
#shard ⇒ Object
219
220
221
|
# File 'lib/switchman/active_record/base.rb', line 219
def shard
@shard || fallback_shard
end
|
#shard=(new_shard) ⇒ Object
223
224
225
226
227
228
229
230
231
232
233
234
235
236
|
# File 'lib/switchman/active_record/base.rb', line 223
def shard=(new_shard)
raise ::ActiveRecord::ReadOnlyRecord if !new_record? || @shard_set_in_stone
if shard == new_shard
@loaded_from_shard = new_shard
return
end
attributes.each do |attr, value|
self[attr] = Shard.relative_id_for(value, shard, new_shard) if self.class.sharded_column?(attr)
end
@loaded_from_shard = new_shard
@shard = new_shard
end
|
#to_param ⇒ Object
282
283
284
285
|
# File 'lib/switchman/active_record/base.rb', line 282
def to_param
short_id = Shard.short_id_for(id)
short_id&.to_s
end
|
#transaction ⇒ Object
265
266
267
268
269
|
# File 'lib/switchman/active_record/base.rb', line 265
def transaction(...)
shard.activate(self.class.connection_class_for_self) do
self.class.transaction(...)
end
end
|
#update_columns ⇒ Object
293
294
295
296
|
# File 'lib/switchman/active_record/base.rb', line 293
def update_columns(*)
db = shard.database_server
db.unguard { super }
end
|
#with_transaction_returning_status ⇒ Object
271
272
273
274
275
276
|
# File 'lib/switchman/active_record/base.rb', line 271
def with_transaction_returning_status
shard.activate(self.class.connection_class_for_self) do
db = Shard.current(self.class.connection_class_for_self).database_server
db.unguard { super }
end
end
|