switchman 4.0.0 → 4.2.0

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.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/lib/switchman/active_record/abstract_adapter.rb +1 -7
  3. data/lib/switchman/active_record/associations.rb +44 -60
  4. data/lib/switchman/active_record/attribute_methods.rb +34 -27
  5. data/lib/switchman/active_record/base.rb +12 -61
  6. data/lib/switchman/active_record/calculations.rb +37 -48
  7. data/lib/switchman/active_record/connection_pool.rb +37 -23
  8. data/lib/switchman/active_record/database_configurations.rb +7 -19
  9. data/lib/switchman/active_record/finder_methods.rb +21 -45
  10. data/lib/switchman/active_record/log_subscriber.rb +1 -10
  11. data/lib/switchman/active_record/migration.rb +12 -24
  12. data/lib/switchman/active_record/persistence.rb +1 -1
  13. data/lib/switchman/active_record/postgresql_adapter.rb +26 -12
  14. data/lib/switchman/active_record/query_cache.rb +22 -42
  15. data/lib/switchman/active_record/query_methods.rb +63 -22
  16. data/lib/switchman/active_record/reflection.rb +9 -2
  17. data/lib/switchman/active_record/relation.rb +56 -3
  18. data/lib/switchman/active_record/spawn_methods.rb +1 -5
  19. data/lib/switchman/active_record/statement_cache.rb +2 -2
  20. data/lib/switchman/active_record/table_definition.rb +1 -1
  21. data/lib/switchman/active_record/test_fixtures.rb +71 -35
  22. data/lib/switchman/arel.rb +0 -25
  23. data/lib/switchman/database_server.rb +5 -9
  24. data/lib/switchman/engine.rb +10 -5
  25. data/lib/switchman/shard.rb +9 -11
  26. data/lib/switchman/sharded_instrumenter.rb +1 -1
  27. data/lib/switchman/test_helper.rb +1 -1
  28. data/lib/switchman/version.rb +1 -1
  29. data/lib/tasks/switchman.rake +1 -1
  30. metadata +33 -19
@@ -28,15 +28,15 @@ module Switchman
28
28
  relation
29
29
  end
30
30
 
31
- def new(*, &block)
31
+ def new(*, &)
32
32
  primary_shard.activate(klass.connection_class_for_self) { super }
33
33
  end
34
34
 
35
- def create(*, &block)
35
+ def create(*, &)
36
36
  primary_shard.activate(klass.connection_class_for_self) { super }
37
37
  end
38
38
 
39
- def create!(*, &block)
39
+ def create!(*, &)
40
40
  primary_shard.activate(klass.connection_class_for_self) { super }
41
41
  end
42
42
 
@@ -73,6 +73,59 @@ module Switchman
73
73
  RUBY
74
74
  end
75
75
 
76
+ # https://github.com/rails/rails/commit/ed2c15b52450ff927a05629f031376f25b670335
77
+ # once the minimum version is Rails 7.2, we can drop this separate module
78
+ module InsertUpsertAll
79
+ %w[insert_all upsert_all].each do |method|
80
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
81
+ def #{method}(attributes, returning: nil, **)
82
+ scope = self != ::ActiveRecord::Base && current_scope
83
+ if (target_shard = scope&.primary_shard) == (current_shard = Shard.current(connection_class_for_self))
84
+ scope = nil
85
+ end
86
+ if scope
87
+ dupped = false
88
+ attributes.each_with_index do |hash, i|
89
+ if dupped || hash.any? { |k, v| sharded_column?(k) }
90
+ unless dupped
91
+ attributes = attributes.dup
92
+ dupped = true
93
+ end
94
+ attributes[i] = hash.to_h do |k, v|
95
+ if sharded_column?(k)
96
+ [k, Shard.relative_id_for(v, current_shard, target_shard)]
97
+ else
98
+ [k, v]
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ if scope
106
+ scope.activate do
107
+ db = Shard.current(connection_class_for_self).database_server
108
+ result = db.unguard { super }
109
+ if result&.columns&.any? { |c| sharded_column?(c) }
110
+ transposed_rows = result.rows.map do |row|
111
+ row.map.with_index do |value, i|
112
+ sharded_column?(result.columns[i]) ? Shard.relative_id_for(value, target_shard, current_shard) : value
113
+ end
114
+ end
115
+ result = ::ActiveRecord::Result.new(result.columns, transposed_rows, result.column_types)
116
+ end
117
+
118
+ result
119
+ end
120
+ else
121
+ db = Shard.current(connection_class_for_self).database_server
122
+ db.unguard { super }
123
+ end
124
+ end
125
+ RUBY
126
+ end
127
+ end
128
+
76
129
  def find_ids_in_ranges(options = {})
77
130
  is_integer = columns_hash[primary_key.to_s].type == :integer
78
131
  loose_mode = options[:loose] && is_integer
@@ -62,16 +62,12 @@ module Switchman
62
62
  if primary_shard != final_primary_shard && rhs.primary_shard != final_primary_shard
63
63
  shard!(final_primary_shard)
64
64
  rhs = rhs.shard(final_primary_shard)
65
- super(rhs)
66
65
  elsif primary_shard != final_primary_shard
67
66
  shard!(final_primary_shard)
68
- super(rhs)
69
67
  elsif rhs.primary_shard != final_primary_shard
70
68
  rhs = rhs.shard(final_primary_shard)
71
- super(rhs)
72
- else
73
- super
74
69
  end
70
+ super
75
71
 
76
72
  self.shard_value = final_shard_value
77
73
  self.shard_source_value = final_shard_source_value
@@ -29,14 +29,14 @@ module Switchman
29
29
  params, connection = args
30
30
  klass = @klass
31
31
  target_shard = nil
32
- if (primary_index = bind_map.primary_value_index)
32
+ if (primary_index = @bind_map.primary_value_index)
33
33
  primary_value = params[primary_index]
34
34
  target_shard = Shard.local_id_for(primary_value)[1]
35
35
  end
36
36
  current_shard = Shard.current(klass.connection_class_for_self)
37
37
  target_shard ||= current_shard
38
38
 
39
- bind_values = bind_map.bind(params, current_shard, target_shard)
39
+ bind_values = @bind_map.bind(params, current_shard, target_shard)
40
40
 
41
41
  target_shard.activate(klass.connection_class_for_self) do
42
42
  sql = qualified_query_builder(target_shard, klass).sql_for(bind_values, connection)
@@ -4,7 +4,7 @@ module Switchman
4
4
  module ActiveRecord
5
5
  module TableDefinition
6
6
  def column(name, type, limit: nil, **)
7
- Switchman.foreign_key_check(name, type, limit: limit)
7
+ Switchman.foreign_key_check(name, type, limit:)
8
8
  super
9
9
  end
10
10
  end
@@ -4,49 +4,85 @@ module Switchman
4
4
  module ActiveRecord
5
5
  module TestFixtures
6
6
  FORBIDDEN_DB_ENVS = %i[development production].freeze
7
- def setup_fixtures(config = ::ActiveRecord::Base)
8
- super
9
-
10
- return unless run_in_transaction?
11
-
12
- # Replace the one that activerecord natively uses with a switchman-optimized one
13
- ::ActiveSupport::Notifications.unsubscribe(@connection_subscriber)
14
- # Code adapted from the code in rails proper
15
- @connection_subscriber =
16
- ::ActiveSupport::Notifications.subscribe("!connection.active_record") do |_, _, _, _, payload|
17
- spec_name = if ::Rails.version < "7.1"
18
- payload[:spec_name] if payload.key?(:spec_name)
19
- elsif payload.key?(:connection_name)
20
- payload[:connection_name]
21
- end
22
- shard = payload[:shard] if payload.key?(:shard)
23
7
 
24
- if spec_name && !FORBIDDEN_DB_ENVS.include?(shard)
25
- begin
26
- connection = ::ActiveRecord::Base.connection_handler.retrieve_connection(spec_name, shard: shard)
27
- connection.connect! if ::Rails.version >= "7.1" # eagerly validate the connection
28
- rescue ::ActiveRecord::ConnectionNotEstablished, ::ActiveRecord::NoDatabaseError
29
- connection = nil
30
- end
8
+ if ::Rails.version < "7.2"
9
+ def setup_fixtures(config = ::ActiveRecord::Base)
10
+ super
11
+ return unless run_in_transaction?
31
12
 
32
- if connection
33
- setup_shared_connection_pool
34
- unless @fixture_connections.include?(connection)
35
- connection.begin_transaction joinable: false, _lazy: false
36
- connection.pool.lock_thread = true if lock_threads
37
- @fixture_connections << connection
13
+ # Replace the one that activerecord natively uses with a switchman-optimized one
14
+ ::ActiveSupport::Notifications.unsubscribe(@connection_subscriber)
15
+ # Code adapted from the code in rails proper
16
+ @connection_subscriber =
17
+ ::ActiveSupport::Notifications.subscribe("!connection.active_record") do |_, _, _, _, payload|
18
+ spec_name = (payload[:connection_name] if payload.key?(:connection_name))
19
+ shard = payload[:shard] if payload.key?(:shard)
20
+
21
+ if spec_name && !FORBIDDEN_DB_ENVS.include?(shard)
22
+ begin
23
+ connection = ::ActiveRecord::Base.connection_handler.retrieve_connection(spec_name, shard: shard)
24
+ connection.connect! # eagerly validate the connection
25
+ rescue ::ActiveRecord::ConnectionNotEstablished
26
+ connection = nil
27
+ end
28
+
29
+ if connection
30
+ setup_shared_connection_pool
31
+ unless @fixture_connections.include?(connection)
32
+ connection.begin_transaction joinable: false, _lazy: false
33
+ connection.pool.lock_thread = true if lock_threads
34
+ @fixture_connections << connection
35
+ end
38
36
  end
39
37
  end
40
38
  end
39
+ end
40
+
41
+ def enlist_fixture_connections
42
+ setup_shared_connection_pool
43
+
44
+ ::ActiveRecord::Base.connection_handler.connection_pool_list(:primary).reject do |cp|
45
+ FORBIDDEN_DB_ENVS.include?(cp.db_config.env_name.to_sym)
46
+ end.map(&:connection)
47
+ end
48
+ else
49
+ def setup_transactional_fixtures
50
+ setup_shared_connection_pool
51
+
52
+ # Begin transactions for connections already established
53
+ # INST: :writing -> :primary
54
+ @fixture_connection_pools = ::ActiveRecord::Base.connection_handler.connection_pool_list(:primary)
55
+ # INST: filter by FORBIDDEN_DB_ENVS
56
+ @fixture_connection_pools = @fixture_connection_pools.reject do |cp|
57
+ FORBIDDEN_DB_ENVS.include?(cp.db_config.env_name.to_sym)
41
58
  end
42
- end
43
59
 
44
- def enlist_fixture_connections
45
- setup_shared_connection_pool
60
+ @fixture_connection_pools.each do |pool|
61
+ pool.pin_connection!(lock_threads)
62
+ pool.lease_connection
63
+ end
64
+
65
+ # When connections are established in the future, begin a transaction too
66
+ @connection_subscriber = ::ActiveSupport::Notifications
67
+ .subscribe("!connection.active_record") do |_, _, _, _, payload|
68
+ connection_name = payload[:connection_name] if payload.key?(:connection_name)
69
+ shard = payload[:shard] if payload.key?(:shard)
70
+
71
+ # INST: filter by FORBIDDEN_DB_ENVS
72
+ if connection_name && !FORBIDDEN_DB_ENVS.include?(shard)
73
+ pool = ::ActiveRecord::Base.connection_handler.retrieve_connection_pool(connection_name, shard: shard)
74
+ if pool
75
+ setup_shared_connection_pool
46
76
 
47
- ::ActiveRecord::Base.connection_handler.connection_pool_list(:primary).reject do |cp|
48
- FORBIDDEN_DB_ENVS.include?(cp.db_config.env_name.to_sym)
49
- end.map(&:connection)
77
+ unless @fixture_connection_pools.include?(pool)
78
+ pool.pin_connection!(lock_threads)
79
+ pool.lease_connection
80
+ @fixture_connection_pools << pool
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
50
86
  end
51
87
  end
52
88
  end
@@ -38,31 +38,6 @@ module Switchman
38
38
  collector << quote_local_table_name(join_name) << "." << quote_column_name(o.name)
39
39
  end
40
40
 
41
- if ::Rails.version < "7.1"
42
- def visit_Arel_Nodes_HomogeneousIn(o, collector)
43
- collector.preparable = false
44
-
45
- collector << quote_local_table_name(o.table_name) << "." << quote_column_name(o.column_name)
46
-
47
- collector << if o.type == :in
48
- " IN ("
49
- else
50
- " NOT IN ("
51
- end
52
-
53
- values = o.casted_values
54
-
55
- if values.empty?
56
- collector << @connection.quote(nil)
57
- else
58
- collector.add_binds(values, o.proc_for_binds, &bind_block)
59
- end
60
-
61
- collector << ")"
62
- collector
63
- end
64
- end
65
-
66
41
  # rubocop:enable Naming/MethodName
67
42
  # rubocop:enable Naming/MethodParameterName
68
43
 
@@ -121,7 +121,7 @@ module Switchman
121
121
  Shard.sharded_models.each do |klass|
122
122
  self.class.all_roles.each do |role|
123
123
  klass.connection_handler.remove_connection_pool(klass.connection_specification_name,
124
- role: role,
124
+ role:,
125
125
  shard: id.to_sym)
126
126
  end
127
127
  end
@@ -218,7 +218,7 @@ module Switchman
218
218
  if config_create_statement
219
219
  create_commands = Array(config_create_statement).dup
220
220
  create_statement = lambda {
221
- create_commands.map { |statement| format(statement, name: name, password: password) }
221
+ create_commands.map { |statement| format(statement, name:, password:) }
222
222
  }
223
223
  end
224
224
 
@@ -236,8 +236,8 @@ module Switchman
236
236
  self.class.creating_new_shard = true
237
237
  DatabaseServer.send(:reference_role, :deploy)
238
238
  ::ActiveRecord::Base.connected_to(shard: self.id.to_sym, role: :deploy) do
239
- shard = Shard.create!(id: id,
240
- name: name,
239
+ shard = Shard.create!(id:,
240
+ name:,
241
241
  database_server_id: self.id)
242
242
  if create_statement
243
243
  if ::ActiveRecord::Base.connection.select_value(
@@ -259,11 +259,7 @@ module Switchman
259
259
  unless schema == false
260
260
  shard.activate do
261
261
  ::ActiveRecord::Base.connection.transaction(requires_new: true) do
262
- if ::Rails.version < "7.1"
263
- ::ActiveRecord::Base.connection.migration_context.migrate
264
- else
265
- ::ActiveRecord::MigrationContext.new(::ActiveRecord::Migrator.migrations_paths).migrate
266
- end
262
+ ::ActiveRecord::MigrationContext.new(::ActiveRecord::Migrator.migrations_paths).migrate
267
263
  end
268
264
 
269
265
  ::ActiveRecord::Base.descendants.reject do |m|
@@ -4,8 +4,6 @@ module Switchman
4
4
  class Engine < ::Rails::Engine
5
5
  isolate_namespace Switchman
6
6
 
7
- # enable Rails 6.1 style connection handling
8
- config.active_record.legacy_connection_handling = false if ::Rails.version < "7.1"
9
7
  config.active_record.writing_role = :primary
10
8
 
11
9
  ::GuardRail.singleton_class.prepend(GuardRail::ClassMethods)
@@ -47,12 +45,18 @@ module Switchman
47
45
  ActiveRecord::Associations::Preloader::Association::LoaderRecords
48
46
  )
49
47
  ::ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend(ActiveRecord::AbstractAdapter)
50
- unless ::Rails.version < "7.1"
51
- ::ActiveRecord::ConnectionAdapters::ConnectionHandler.prepend(ActiveRecord::ConnectionHandler)
52
- end
48
+ ::ActiveRecord::ConnectionAdapters::ConnectionHandler.prepend(ActiveRecord::ConnectionHandler)
53
49
  ::ActiveRecord::ConnectionAdapters::ConnectionPool.prepend(ActiveRecord::ConnectionPool)
54
50
  ::ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend(ActiveRecord::QueryCache)
55
51
  ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(ActiveRecord::PostgreSQLAdapter)
52
+ # https://github.com/rails/rails/commit/0016280f4fde55d96738887093dc333aae0d107b
53
+ if ::Rails.version < "7.2"
54
+ ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(ActiveRecord::PostgreSQLAdapter::ClassMethods)
55
+ else
56
+ ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.singleton_class.prepend(
57
+ ActiveRecord::PostgreSQLAdapter::ClassMethods
58
+ )
59
+ end
56
60
 
57
61
  ::ActiveRecord::DatabaseConfigurations.prepend(ActiveRecord::DatabaseConfigurations)
58
62
  ::ActiveRecord::DatabaseConfigurations::DatabaseConfig.prepend(
@@ -79,6 +83,7 @@ module Switchman
79
83
  ::ActiveRecord::Relation.include(ActiveRecord::QueryMethods)
80
84
  ::ActiveRecord::Relation.prepend(GuardRail::Relation)
81
85
  ::ActiveRecord::Relation.prepend(ActiveRecord::Relation)
86
+ ::ActiveRecord::Relation.prepend(ActiveRecord::Relation::InsertUpsertAll) if ::Rails.version >= "7.2"
82
87
  ::ActiveRecord::Relation.include(ActiveRecord::SpawnMethods)
83
88
  ::ActiveRecord::Relation.include(CallSuper)
84
89
 
@@ -5,8 +5,10 @@ module Switchman
5
5
  # ten trillion possible ids per shard. yup.
6
6
  IDS_PER_SHARD = 10_000_000_000_000
7
7
 
8
+ # rubocop:disable Style/SymbolProc -- transforming to a lambda produces "no receiver given"
8
9
  # only allow one default
9
10
  validates_uniqueness_of :default, if: ->(s) { s.default? }
11
+ # rubocop:enable Style/SymbolProc
10
12
 
11
13
  after_save :clear_cache
12
14
  after_destroy :clear_cache
@@ -51,7 +53,7 @@ module Switchman
51
53
  return [default] unless default.is_a?(Switchman::Shard)
52
54
  return all if !Switchman.region || DatabaseServer.none?(&:region)
53
55
 
54
- in_region(Switchman.region, include_regionless: include_regionless)
56
+ in_region(Switchman.region, include_regionless:)
55
57
  end)
56
58
 
57
59
  class << self
@@ -141,7 +143,7 @@ module Switchman
141
143
 
142
144
  unless cached_shards.key?(id)
143
145
  cached_shards[id] = Shard.default.activate do
144
- find_cached(["shard", id]) { find_by(id: id) }
146
+ find_cached(["shard", id]) { find_by(id:) }
145
147
  end
146
148
  end
147
149
  cached_shards[id]
@@ -214,11 +216,7 @@ module Switchman
214
216
  # clear connections prior to forking (no more queries will be executed in the parent,
215
217
  # and we want them gone so that we don't accidentally use them post-fork doing something
216
218
  # silly like dealloc'ing prepared statements)
217
- if ::Rails.version < "7.1"
218
- ::ActiveRecord::Base.clear_all_connections!(nil)
219
- else
220
- ::ActiveRecord::Base.connection_handler.clear_all_connections!(:all)
221
- end
219
+ ::ActiveRecord::Base.connection_handler.clear_all_connections!(:all)
222
220
 
223
221
  parent_process_name = sanitized_process_title
224
222
  ret = ::Parallel.map(scopes, in_processes: (scopes.length > 1) ? parallel : 0) do |server, subscope|
@@ -233,7 +231,7 @@ module Switchman
233
231
  Switchman.config[:on_fork_proc]&.call
234
232
  with_each_shard(subscope,
235
233
  classes,
236
- exception: exception,
234
+ exception:,
237
235
  output: output || :decorated) do
238
236
  last_description = Shard.current.description
239
237
  Parallel::ResultWrapper.new(yield)
@@ -459,7 +457,7 @@ module Switchman
459
457
  connects_to_hash.each do |(db_name, role_hash)|
460
458
  role_hash.each_key do |role|
461
459
  role_hash.delete(role) if klass.connection_handler.retrieve_connection_pool(
462
- klass.connection_specification_name, role: role, shard: db_name
460
+ klass.connection_specification_name, role:, shard: db_name
463
461
  )
464
462
  end
465
463
  end
@@ -590,9 +588,9 @@ module Switchman
590
588
  id
591
589
  end
592
590
 
593
- def activate(*classes, &block)
591
+ def activate(*classes, &)
594
592
  shards = hashify_classes(classes)
595
- Shard.activate(shards, &block)
593
+ Shard.activate(shards, &)
596
594
  end
597
595
 
598
596
  # for use from console ONLY
@@ -19,7 +19,7 @@ module Switchman
19
19
  env: @shard_host.pool.connection_class&.current_role
20
20
  }
21
21
  end
22
- super(name, payload)
22
+ super
23
23
  end
24
24
  end
25
25
  end
@@ -63,7 +63,7 @@ module Switchman
63
63
 
64
64
  def find_existing_test_shard(server, name)
65
65
  if server == Shard.default.database_server
66
- server.shards.where(name: name).first
66
+ server.shards.where(name:).first
67
67
  else
68
68
  shard = Shard.where("database_server_id IS NOT NULL AND name=?", name).first
69
69
  # if somehow databases got created in a different order, change the shard to match
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Switchman
4
- VERSION = "4.0.0"
4
+ VERSION = "4.2.0"
5
5
  end
@@ -94,7 +94,7 @@ module Switchman
94
94
  else
95
95
  nil
96
96
  end
97
- Shard.with_each_shard(scope, classes, output: output, **options) do
97
+ Shard.with_each_shard(scope, classes, output:, **options) do
98
98
  shard = Shard.current
99
99
 
100
100
  if log_format == "json"
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: 4.0.0
4
+ version: 4.2.0
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: 2025-02-12 00:00:00.000000000 Z
13
+ date: 2025-08-25 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -18,34 +18,34 @@ dependencies:
18
18
  requirements:
19
19
  - - ">="
20
20
  - !ruby/object:Gem::Version
21
- version: '7.0'
21
+ version: '7.1'
22
22
  - - "<"
23
23
  - !ruby/object:Gem::Version
24
- version: '7.2'
24
+ version: '8.1'
25
25
  type: :runtime
26
26
  prerelease: false
27
27
  version_requirements: !ruby/object:Gem::Requirement
28
28
  requirements:
29
29
  - - ">="
30
30
  - !ruby/object:Gem::Version
31
- version: '7.0'
31
+ version: '7.1'
32
32
  - - "<"
33
33
  - !ruby/object:Gem::Version
34
- version: '7.2'
34
+ version: '8.1'
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: guardrail
37
37
  requirement: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: 3.0.1
41
+ version: 3.1.0
42
42
  type: :runtime
43
43
  prerelease: false
44
44
  version_requirements: !ruby/object:Gem::Requirement
45
45
  requirements:
46
46
  - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: 3.0.1
48
+ version: 3.1.0
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: parallel
51
51
  requirement: !ruby/object:Gem::Requirement
@@ -66,20 +66,20 @@ dependencies:
66
66
  requirements:
67
67
  - - ">="
68
68
  - !ruby/object:Gem::Version
69
- version: '7.0'
69
+ version: '7.1'
70
70
  - - "<"
71
71
  - !ruby/object:Gem::Version
72
- version: '7.2'
72
+ version: '8.1'
73
73
  type: :runtime
74
74
  prerelease: false
75
75
  version_requirements: !ruby/object:Gem::Requirement
76
76
  requirements:
77
77
  - - ">="
78
78
  - !ruby/object:Gem::Version
79
- version: '7.0'
79
+ version: '7.1'
80
80
  - - "<"
81
81
  - !ruby/object:Gem::Version
82
- version: '7.2'
82
+ version: '8.1'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: debug
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -198,14 +198,28 @@ dependencies:
198
198
  requirements:
199
199
  - - "~>"
200
200
  - !ruby/object:Gem::Version
201
- version: '2.2'
201
+ version: '3.0'
202
202
  type: :development
203
203
  prerelease: false
204
204
  version_requirements: !ruby/object:Gem::Requirement
205
205
  requirements:
206
206
  - - "~>"
207
207
  - !ruby/object:Gem::Version
208
- version: '2.2'
208
+ version: '3.0'
209
+ - !ruby/object:Gem::Dependency
210
+ name: rubocop-rspec_rails
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - "~>"
214
+ - !ruby/object:Gem::Version
215
+ version: '2.29'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - "~>"
221
+ - !ruby/object:Gem::Version
222
+ version: '2.29'
209
223
  - !ruby/object:Gem::Dependency
210
224
  name: simplecov
211
225
  requirement: !ruby/object:Gem::Requirement
@@ -290,7 +304,7 @@ licenses:
290
304
  metadata:
291
305
  rubygems_mfa_required: 'true'
292
306
  source_code_uri: https://github.com/instructure/switchman
293
- post_install_message:
307
+ post_install_message:
294
308
  rdoc_options: []
295
309
  require_paths:
296
310
  - lib
@@ -298,15 +312,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
298
312
  requirements:
299
313
  - - ">="
300
314
  - !ruby/object:Gem::Version
301
- version: '3.0'
315
+ version: '3.2'
302
316
  required_rubygems_version: !ruby/object:Gem::Requirement
303
317
  requirements:
304
318
  - - ">="
305
319
  - !ruby/object:Gem::Version
306
320
  version: '0'
307
321
  requirements: []
308
- rubygems_version: 3.2.33
309
- signing_key:
322
+ rubygems_version: 3.4.19
323
+ signing_key:
310
324
  specification_version: 4
311
325
  summary: Rails sharding magic
312
326
  test_files: []