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