switchman 2.0.3 → 2.0.5
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/lib/switchman/active_record/migration.rb +1 -1
- data/lib/switchman/active_record/query_methods.rb +119 -72
- data/lib/switchman/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c544d2ed8498a6aecf33823f39b304393a65f213f6a68bf04f4d36610ebe3ac2
|
4
|
+
data.tar.gz: be685b315997b103dd13376f5223196f1b66a5be490502aac6bc401408899abc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fbdd769d90c831e1bbe6dd39def12775537989346daae7dbbab3103a330b89151e9d1c3b9fe216ab9ade75e3c01ee1b1c91062cc622707c3c2697f7dc3239ea8
|
7
|
+
data.tar.gz: 27d32eefa842a76debb1a1fc7875407b4df1398a45a71419c7cc13045fd8705ff5e4af724478a9cb854d517433ae8d16420baa13fc8e7459ab1953e626c0c80a
|
@@ -31,7 +31,7 @@ module Switchman
|
|
31
31
|
|
32
32
|
module Migrator
|
33
33
|
def generate_migrator_advisory_lock_id
|
34
|
-
shard_name_hash = Zlib.crc32(Shard.current.name)
|
34
|
+
shard_name_hash = Zlib.crc32("#{Shard.current.id}:#{Shard.current.name}")
|
35
35
|
::ActiveRecord::Migrator::MIGRATOR_SALT * shard_name_hash
|
36
36
|
end
|
37
37
|
end
|
@@ -78,6 +78,10 @@ module Switchman
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
|
+
def or(other)
|
82
|
+
super(other.shard(self.primary_shard))
|
83
|
+
end
|
84
|
+
|
81
85
|
private
|
82
86
|
|
83
87
|
if ::Rails.version >= '5.2'
|
@@ -242,92 +246,135 @@ module Switchman
|
|
242
246
|
binds: nil,
|
243
247
|
dup_binds_on_mutation: false)
|
244
248
|
result = predicates.map do |predicate|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
+
transposed, binds = transpose_single_predicate(predicate, source_shard, target_shard, remove_nonlocal_primary_keys,
|
250
|
+
binds: binds, dup_binds_on_mutation: dup_binds_on_mutation)
|
251
|
+
transposed
|
252
|
+
end
|
253
|
+
result = [result, binds]
|
254
|
+
result
|
255
|
+
end
|
249
256
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
257
|
+
def transpose_single_predicate(predicate,
|
258
|
+
source_shard,
|
259
|
+
target_shard,
|
260
|
+
remove_nonlocal_primary_keys = false,
|
261
|
+
binds: nil,
|
262
|
+
dup_binds_on_mutation: false)
|
263
|
+
if predicate.is_a?(::Arel::Nodes::Grouping)
|
264
|
+
return predicate, binds unless predicate.expr.is_a?(::Arel::Nodes::Or)
|
265
|
+
# Dang, we have an OR. OK, that means we have other epxressions below this
|
266
|
+
# level, perhaps many, that may need transposition.
|
267
|
+
# the left side and right side must each be treated as predicate lists and
|
268
|
+
# transformed in kind, if neither of them changes we can just return the grouping as is.
|
269
|
+
# hold on, it's about to get recursive...
|
270
|
+
#
|
271
|
+
# TODO: "binds" is getting passed up and down
|
272
|
+
# this stack purely because of the necessary handling for rails <5.2
|
273
|
+
# Dropping support for 5.2 means we can remove the "binds" argument from
|
274
|
+
# all of this and yank the conditional below where we monkey with their instance state.
|
275
|
+
or_expr = predicate.expr
|
276
|
+
left_node = or_expr.left
|
277
|
+
right_node = or_expr.right
|
278
|
+
left_predicates = left_node.children
|
279
|
+
right_predicates = right_node.children
|
280
|
+
new_left_predicates, binds = transpose_predicates(left_predicates, source_shard,
|
281
|
+
target_shard, remove_nonlocal_primary_keys,
|
282
|
+
binds: binds, dup_binds_on_mutation: dup_binds_on_mutation)
|
283
|
+
new_right_predicates, binds = transpose_predicates(right_predicates, source_shard,
|
284
|
+
target_shard, remove_nonlocal_primary_keys,
|
285
|
+
binds: binds, dup_binds_on_mutation: dup_binds_on_mutation)
|
286
|
+
if new_left_predicates != left_predicates
|
287
|
+
left_node.instance_variable_set(:@children, new_left_predicates)
|
288
|
+
end
|
289
|
+
if new_right_predicates != right_predicates
|
290
|
+
right_node.instance_variable_set(:@children, new_right_predicates)
|
291
|
+
end
|
292
|
+
return predicate, binds
|
293
|
+
end
|
294
|
+
return predicate, binds unless predicate.is_a?(::Arel::Nodes::Binary)
|
295
|
+
return predicate, binds unless predicate.left.is_a?(::Arel::Attributes::Attribute)
|
296
|
+
relation, column = relation_and_column(predicate.left)
|
297
|
+
return predicate, binds unless (type = transposable_attribute_type(relation, column))
|
254
298
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
Shard.current(klass.shard_category)
|
260
|
-
elsif type == :foreign
|
261
|
-
source_shard_for_foreign_key(relation, column)
|
262
|
-
end
|
299
|
+
remove = true if type == :primary &&
|
300
|
+
remove_nonlocal_primary_keys &&
|
301
|
+
predicate.left.relation.model == klass &&
|
302
|
+
predicate.is_a?(::Arel::Nodes::Equality)
|
263
303
|
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
304
|
+
current_source_shard =
|
305
|
+
if source_shard
|
306
|
+
source_shard
|
307
|
+
elsif type == :primary
|
308
|
+
Shard.current(klass.shard_category)
|
309
|
+
elsif type == :foreign
|
310
|
+
source_shard_for_foreign_key(relation, column)
|
311
|
+
end
|
312
|
+
|
313
|
+
if ::Rails.version >= "5.2"
|
314
|
+
new_right_value =
|
315
|
+
case predicate.right
|
274
316
|
when Array
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
317
|
+
predicate.right.map {|val| transpose_predicate_value(val, current_source_shard, target_shard, type, remove) }
|
318
|
+
else
|
319
|
+
transpose_predicate_value(predicate.right, current_source_shard, target_shard, type, remove)
|
320
|
+
end
|
321
|
+
else
|
322
|
+
new_right_value = case predicate.right
|
323
|
+
when Array
|
324
|
+
local_ids = []
|
325
|
+
predicate.right.each do |value|
|
326
|
+
local_id = Shard.relative_id_for(value, current_source_shard, target_shard)
|
327
|
+
next unless local_id
|
328
|
+
unless remove && local_id > Shard::IDS_PER_SHARD
|
329
|
+
if value.is_a?(::Arel::Nodes::Casted)
|
330
|
+
if local_id == value.val
|
331
|
+
local_id = value
|
332
|
+
elsif local_id != value
|
333
|
+
local_id = value.class.new(local_id, value.attribute)
|
286
334
|
end
|
287
|
-
local_ids << local_id
|
288
335
|
end
|
336
|
+
local_ids << local_id
|
289
337
|
end
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
338
|
+
end
|
339
|
+
local_ids
|
340
|
+
when ::Arel::Nodes::BindParam
|
341
|
+
# look for a bind param with a matching column name
|
342
|
+
if binds && bind = binds.detect{|b| b&.name.to_s == predicate.left.name.to_s}
|
343
|
+
# before we mutate, dup
|
344
|
+
if dup_binds_on_mutation
|
345
|
+
binds = binds.map(&:dup)
|
346
|
+
dup_binds_on_mutation = false
|
347
|
+
bind = binds.find { |b| b&.name.to_s == predicate.left.name.to_s }
|
348
|
+
end
|
349
|
+
if bind.value.is_a?(::ActiveRecord::StatementCache::Substitute)
|
350
|
+
bind.value.sharded = true # mark for transposition later
|
351
|
+
bind.value.primary = true if type == :primary
|
352
|
+
else
|
353
|
+
local_id = Shard.relative_id_for(bind.value, current_source_shard, target_shard)
|
354
|
+
local_id = [] if remove && local_id > Shard::IDS_PER_SHARD
|
355
|
+
bind.instance_variable_set(:@value, local_id)
|
356
|
+
bind.instance_variable_set(:@value_for_database, nil)
|
309
357
|
end
|
310
|
-
predicate.right
|
311
|
-
else
|
312
|
-
local_id = Shard.relative_id_for(predicate.right, current_source_shard, target_shard) || predicate.right
|
313
|
-
local_id = [] if remove && local_id.is_a?(Integer) && local_id > Shard::IDS_PER_SHARD
|
314
|
-
local_id
|
315
358
|
end
|
359
|
+
predicate.right
|
360
|
+
else
|
361
|
+
local_id = Shard.relative_id_for(predicate.right, current_source_shard, target_shard) || predicate.right
|
362
|
+
local_id = [] if remove && local_id.is_a?(Integer) && local_id > Shard::IDS_PER_SHARD
|
363
|
+
local_id
|
316
364
|
end
|
317
|
-
|
365
|
+
end
|
366
|
+
out_predicate = if new_right_value == predicate.right
|
367
|
+
predicate
|
368
|
+
elsif predicate.right.is_a?(::Arel::Nodes::Casted)
|
369
|
+
if new_right_value == predicate.right.val
|
318
370
|
predicate
|
319
|
-
elsif predicate.right.is_a?(::Arel::Nodes::Casted)
|
320
|
-
if new_right_value == predicate.right.val
|
321
|
-
predicate
|
322
|
-
else
|
323
|
-
predicate.class.new(predicate.left, predicate.right.class.new(new_right_value, predicate.right.attribute))
|
324
|
-
end
|
325
371
|
else
|
326
|
-
predicate.class.new(predicate.left, new_right_value)
|
372
|
+
predicate.class.new(predicate.left, predicate.right.class.new(new_right_value, predicate.right.attribute))
|
327
373
|
end
|
374
|
+
else
|
375
|
+
predicate.class.new(predicate.left, new_right_value)
|
328
376
|
end
|
329
|
-
|
330
|
-
result
|
377
|
+
return out_predicate, binds
|
331
378
|
end
|
332
379
|
|
333
380
|
def transpose_predicate_value(value, current_shard, target_shard, attribute_type, remove_non_local_ids)
|
data/lib/switchman/version.rb
CHANGED
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: switchman
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cody Cutrer
|
8
8
|
- James Williams
|
9
9
|
- Jacob Fugal
|
10
|
-
autorequire:
|
10
|
+
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2021-
|
13
|
+
date: 2021-03-02 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: railties
|
@@ -257,7 +257,7 @@ homepage: http://www.instructure.com/
|
|
257
257
|
licenses:
|
258
258
|
- MIT
|
259
259
|
metadata: {}
|
260
|
-
post_install_message:
|
260
|
+
post_install_message:
|
261
261
|
rdoc_options: []
|
262
262
|
require_paths:
|
263
263
|
- lib
|
@@ -272,8 +272,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
272
272
|
- !ruby/object:Gem::Version
|
273
273
|
version: '0'
|
274
274
|
requirements: []
|
275
|
-
rubygems_version: 3.
|
276
|
-
signing_key:
|
275
|
+
rubygems_version: 3.0.3
|
276
|
+
signing_key:
|
277
277
|
specification_version: 4
|
278
278
|
summary: Rails sharding magic
|
279
279
|
test_files: []
|