switchman 2.0.3 → 2.0.5

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: 5205c32993056a0fa71d272a95c5306d17762b31971c6242b0fd40e3b587a591
4
- data.tar.gz: fd445dbeb2e0654e591a461637fa3720a7b335d1307e6ecf289ce88caac17d2d
3
+ metadata.gz: c544d2ed8498a6aecf33823f39b304393a65f213f6a68bf04f4d36610ebe3ac2
4
+ data.tar.gz: be685b315997b103dd13376f5223196f1b66a5be490502aac6bc401408899abc
5
5
  SHA512:
6
- metadata.gz: a7db2fab2fb62cae74a845bff7373584c75057e2e9464ffacc130d053e78b6949e6c971aa29372b0f31ef6d25aba389b1c420fc601e18ae7cd8f1ac89b6b85e5
7
- data.tar.gz: aa2fcb0523b80507b35f5e2b9cdf14f3793b8354ba26bf8dddd000d6da7d6a4abfc50eb7ef45b4013516282111aabe3dd31b264764378fc9abbc1cb1f5bee9e9
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
- next predicate unless predicate.is_a?(::Arel::Nodes::Binary)
246
- next predicate unless predicate.left.is_a?(::Arel::Attributes::Attribute)
247
- relation, column = relation_and_column(predicate.left)
248
- next predicate unless (type = transposable_attribute_type(relation, column))
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
- remove = true if type == :primary &&
251
- remove_nonlocal_primary_keys &&
252
- predicate.left.relation.model == klass &&
253
- predicate.is_a?(::Arel::Nodes::Equality)
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
- current_source_shard =
256
- if source_shard
257
- source_shard
258
- elsif type == :primary
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
- if ::Rails.version >= "5.2"
265
- new_right_value =
266
- case predicate.right
267
- when Array
268
- predicate.right.map {|val| transpose_predicate_value(val, current_source_shard, target_shard, type, remove) }
269
- else
270
- transpose_predicate_value(predicate.right, current_source_shard, target_shard, type, remove)
271
- end
272
- else
273
- new_right_value = case predicate.right
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
- local_ids = []
276
- predicate.right.each do |value|
277
- local_id = Shard.relative_id_for(value, current_source_shard, target_shard)
278
- next unless local_id
279
- unless remove && local_id > Shard::IDS_PER_SHARD
280
- if value.is_a?(::Arel::Nodes::Casted)
281
- if local_id == value.val
282
- local_id = value
283
- elsif local_id != value
284
- local_id = value.class.new(local_id, value.attribute)
285
- end
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
- local_ids
291
- when ::Arel::Nodes::BindParam
292
- # look for a bind param with a matching column name
293
- if binds && bind = binds.detect{|b| b&.name.to_s == predicate.left.name.to_s}
294
- # before we mutate, dup
295
- if dup_binds_on_mutation
296
- binds = binds.map(&:dup)
297
- dup_binds_on_mutation = false
298
- bind = binds.find { |b| b&.name.to_s == predicate.left.name.to_s }
299
- end
300
- if bind.value.is_a?(::ActiveRecord::StatementCache::Substitute)
301
- bind.value.sharded = true # mark for transposition later
302
- bind.value.primary = true if type == :primary
303
- else
304
- local_id = Shard.relative_id_for(bind.value, current_source_shard, target_shard)
305
- local_id = [] if remove && local_id > Shard::IDS_PER_SHARD
306
- bind.instance_variable_set(:@value, local_id)
307
- bind.instance_variable_set(:@value_for_database, nil)
308
- end
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
- if new_right_value == predicate.right
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
- result = [result, binds]
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)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Switchman
4
- VERSION = "2.0.3"
4
+ VERSION = "2.0.5"
5
5
  end
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.3
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-01-21 00:00:00.000000000 Z
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.1.4
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: []