switchman 3.5.11 → 3.5.13

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: 66fb79b6ead1a010749a4c707e9d3b6f1d1af3af3ce79748c12a4c74940d1238
4
- data.tar.gz: c8cd71c46f6dc930d6129b8b7ea033286c02a81ddd650f69580d310865f7065c
3
+ metadata.gz: c0ab0712ea0711e482d32ddf5ce6ec740b399b6dc8074ea86eaaa092c13bbdd1
4
+ data.tar.gz: a3e43929c88727da33b2954966f7cf357bd2b8793eed33563f57908839e2d97d
5
5
  SHA512:
6
- metadata.gz: 7d69de4d0dccbffede8882e50144aaa35840b7374e2d4265ff01eb3a78f3b5001934886dedb0e0e67f23c31fc6ee8a2b9aad1dca2e7fa093e16dd5deac85cada
7
- data.tar.gz: cfb5b3f62773187207904ca822188344cf3c3d4d6d24d27d0b801d071bdf98b6250ad314531a6dce0e06e8c0a13474486a37dbc382c8b4ebedb18cab923db5a3
6
+ metadata.gz: 67a005a7e156773576077ade7723e1500d291e782cdfb4af9662cef6ba2a217b2e0743aaea8a5e8bffc1777295baf465f9d7678f6d8fa6c681215b1ad9c5817a
7
+ data.tar.gz: 7e72531b558a3fc0d447d63efeec37b5a0480ebe873ff2e76fb6334927aee10d5342a92b0be8336bd324da57c2df6ff154b5efb2d88b5cc0e9e7b16f60bc6c78
@@ -27,8 +27,10 @@ module Switchman
27
27
  quote_table_name(name)
28
28
  end
29
29
 
30
- def schema_migration
31
- ::ActiveRecord::SchemaMigration
30
+ if ::Rails.version < "7.1"
31
+ def schema_migration
32
+ ::ActiveRecord::SchemaMigration
33
+ end
32
34
  end
33
35
 
34
36
  protected
@@ -298,11 +298,48 @@ module Switchman
298
298
  record.has_attribute?(reflection.foreign_key) && record.send(reflection.foreign_key) != key
299
299
  end
300
300
 
301
- def save_belongs_to_association(reflection)
302
- # this seems counter-intuitive, but the autosave code will assign to attribute bypassing switchman,
303
- # after reading the id attribute _without_ bypassing switchman. So we need Shard.current for the
304
- # category of the associated record to match Shard.current for the category of self
305
- shard.activate(connection_class_for_self_for_reflection(reflection)) { super }
301
+ if ::Rails.version < "7.1"
302
+ def save_belongs_to_association(reflection)
303
+ # this seems counter-intuitive, but the autosave code will assign to attribute bypassing switchman,
304
+ # after reading the id attribute _without_ bypassing switchman. So we need Shard.current for the
305
+ # category of the associated record to match Shard.current for the category of self
306
+ shard.activate(connection_class_for_self_for_reflection(reflection)) { super }
307
+ end
308
+ else
309
+ def save_belongs_to_association(reflection)
310
+ association = association_instance_get(reflection.name)
311
+ return unless association&.loaded? && !association.stale_target?
312
+
313
+ record = association.load_target
314
+ return unless record && !record.destroyed?
315
+
316
+ autosave = reflection.options[:autosave]
317
+
318
+ if autosave && record.marked_for_destruction?
319
+ foreign_key = Array(reflection.foreign_key)
320
+ foreign_key.each { |key| self[key] = nil }
321
+ record.destroy
322
+ elsif autosave != false
323
+ if record.new_record? || (autosave && record.changed_for_autosave?)
324
+ saved = record.save(validate: !autosave)
325
+ end
326
+
327
+ if association.updated?
328
+ primary_key = Array(compute_primary_key(reflection, record)).map(&:to_s)
329
+ foreign_key = Array(reflection.foreign_key)
330
+
331
+ primary_key_foreign_key_pairs = primary_key.zip(foreign_key)
332
+ primary_key_foreign_key_pairs.each do |pk, fk|
333
+ # Notable change: add relative_id_for here
334
+ association_id = Shard.relative_id_for(record._read_attribute(pk), record.shard, shard)
335
+ self[fk] = association_id unless self[fk] == association_id
336
+ end
337
+ association.loaded!
338
+ end
339
+
340
+ saved if autosave
341
+ end
342
+ end
306
343
  end
307
344
  end
308
345
  end
@@ -57,7 +57,7 @@ module Switchman
57
57
  end
58
58
 
59
59
  def clear_query_caches_for_current_thread
60
- ::ActiveRecord::Base.connection_handler.connection_pool_list.each do |pool|
60
+ ::ActiveRecord::Base.connection_handler.connection_pool_list(:all).each do |pool|
61
61
  pool.connection(switch_shard: false).clear_query_cache if pool.active_connection?
62
62
  end
63
63
  end
@@ -158,7 +158,15 @@ module Switchman
158
158
  end
159
159
 
160
160
  @loaded_from_shard ||= Shard.current(self.class.connection_class_for_self)
161
- readonly! if shadow_record? && !Switchman.config[:writable_shadow_records]
161
+ if shadow_record? && !Switchman.config[:writable_shadow_records]
162
+ @readonly = true
163
+ @readonly_from_shadow ||= true
164
+ end
165
+ super
166
+ end
167
+
168
+ def readonly!
169
+ @readonly_from_shadow = false
162
170
  super
163
171
  end
164
172
 
@@ -257,9 +265,9 @@ module Switchman
257
265
  result
258
266
  end
259
267
 
260
- def transaction(**kwargs, &block)
268
+ def transaction(...)
261
269
  shard.activate(self.class.connection_class_for_self) do
262
- self.class.transaction(**kwargs, &block)
270
+ self.class.transaction(...)
263
271
  end
264
272
  end
265
273
 
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Switchman
4
+ module ActiveRecord
5
+ module ConnectionHandler
6
+ def resolve_pool_config(config, connection_name, role, shard)
7
+ ret = super
8
+ # Make *all* pool configs use the same schema reflection
9
+ ret.schema_reflection = ConnectionHandler.global_schema_reflection
10
+ ret
11
+ end
12
+
13
+ def self.global_schema_reflection
14
+ @global_schema_reflection ||= ::ActiveRecord::ConnectionAdapters::SchemaReflection.new(nil)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -3,22 +3,24 @@
3
3
  module Switchman
4
4
  module ActiveRecord
5
5
  module ConnectionPool
6
- def get_schema_cache(connection)
7
- self.schema_cache ||= SharedSchemaCache.get_schema_cache(connection)
8
- self.schema_cache.connection = connection
6
+ if ::Rails.version < "7.1"
7
+ def get_schema_cache(connection)
8
+ self.schema_cache ||= SharedSchemaCache.get_schema_cache(connection)
9
+ self.schema_cache.connection = connection
9
10
 
10
- self.schema_cache
11
- end
11
+ self.schema_cache
12
+ end
12
13
 
13
- # rubocop:disable Naming/AccessorMethodName override method
14
- def set_schema_cache(cache)
15
- schema_cache = get_schema_cache(cache.connection)
14
+ # rubocop:disable Naming/AccessorMethodName override method
15
+ def set_schema_cache(cache)
16
+ schema_cache = get_schema_cache(cache.connection)
16
17
 
17
- cache.instance_variables.each do |x|
18
- schema_cache.instance_variable_set(x, cache.instance_variable_get(x))
18
+ cache.instance_variables.each do |x|
19
+ schema_cache.instance_variable_set(x, cache.instance_variable_get(x))
20
+ end
19
21
  end
22
+ # rubocop:enable Naming/AccessorMethodName override method
20
23
  end
21
- # rubocop:enable Naming/AccessorMethodName override method
22
24
 
23
25
  def default_schema
24
26
  connection unless @schemas
@@ -7,14 +7,26 @@ module Switchman
7
7
  # since all should point to the same data, even if multiple are writable
8
8
  # (Picks 'primary' since it is guaranteed to exist and switchman handles activating
9
9
  # deploy through other means)
10
- def configs_for(include_replicas: false, name: nil, **)
11
- res = super
12
- if name && !include_replicas
13
- return nil unless name.end_with?("primary")
14
- elsif !include_replicas
15
- return res.select { |config| config.name.end_with?("primary") }
10
+ if ::Rails.version < "7.1"
11
+ def configs_for(include_replicas: false, name: nil, **)
12
+ res = super
13
+ if name && !include_replicas
14
+ return nil unless name.end_with?("primary")
15
+ elsif !include_replicas
16
+ return res.select { |config| config.name.end_with?("primary") }
17
+ end
18
+ res
19
+ end
20
+ else
21
+ def configs_for(include_hidden: false, name: nil, **)
22
+ res = super
23
+ if name && !include_hidden
24
+ return nil unless name.end_with?("primary")
25
+ elsif !include_hidden
26
+ return res.select { |config| config.name.end_with?("primary") }
27
+ end
28
+ res
16
29
  end
17
- res
18
30
  end
19
31
 
20
32
  private
@@ -42,26 +42,56 @@ module Switchman
42
42
  primary_shard.activate { super }
43
43
  end
44
44
 
45
- def exists?(conditions = :none)
46
- conditions = conditions.id if ::ActiveRecord::Base === conditions
47
- return false unless conditions
45
+ if ::Rails.version < "7.1"
46
+ def exists?(conditions = :none)
47
+ conditions = conditions.id if ::ActiveRecord::Base === conditions
48
+ return false unless conditions
48
49
 
49
- relation = apply_join_dependency(eager_loading: false)
50
- return false if ::ActiveRecord::NullRelation === relation
50
+ relation = apply_join_dependency(eager_loading: false)
51
+ return false if ::ActiveRecord::NullRelation === relation
51
52
 
52
- relation = relation.except(:select, :order).select("1 AS one").limit(1)
53
+ relation = relation.except(:select, :order).select("1 AS one").limit(1)
53
54
 
54
- case conditions
55
- when Array, Hash
56
- relation = relation.where(conditions)
57
- else
58
- relation = relation.where(table[primary_key].eq(conditions)) if conditions != :none
55
+ case conditions
56
+ when Array, Hash
57
+ relation = relation.where(conditions)
58
+ else
59
+ relation = relation.where(table[primary_key].eq(conditions)) if conditions != :none
60
+ end
61
+
62
+ relation.activate do |shard_rel|
63
+ return true if connection.select_value(shard_rel.arel, "#{name} Exists")
64
+ end
65
+ false
59
66
  end
67
+ else
68
+ def exists?(conditions = :none)
69
+ return false if @none
70
+
71
+ if Base === conditions
72
+ raise ArgumentError, <<-TEXT.squish
73
+ You are passing an instance of ActiveRecord::Base to `exists?`.
74
+ Please pass the id of the object by calling `.id`.
75
+ TEXT
76
+ end
60
77
 
61
- relation.activate do |shard_rel|
62
- return true if connection.select_value(shard_rel.arel, "#{name} Exists")
78
+ return false if !conditions || limit_value == 0 # rubocop:disable Style/NumericPredicate
79
+
80
+ if eager_loading?
81
+ relation = apply_join_dependency(eager_loading: false)
82
+ return relation.exists?(conditions)
83
+ end
84
+
85
+ relation = construct_relation_for_exists(conditions)
86
+ return false if relation.where_clause.contradiction?
87
+
88
+ relation.activate do |shard_rel|
89
+ return true if skip_query_cache_if_necessary do
90
+ connection.select_rows(shard_rel.arel, "#{name} Exists?").size == 1
91
+ end
92
+ end
93
+ false
63
94
  end
64
- false
65
95
  end
66
96
  end
67
97
  end
@@ -5,8 +5,10 @@ module Switchman
5
5
  module LogSubscriber
6
6
  # sadly, have to completely replace this
7
7
  def sql(event)
8
- self.class.runtime += event.duration
9
- return unless logger.debug?
8
+ if ::Rails.version < "7.1"
9
+ self.class.runtime += event.duration
10
+ return unless logger.debug?
11
+ end
10
12
 
11
13
  payload = event.payload
12
14
 
@@ -27,7 +29,11 @@ module Switchman
27
29
  end
28
30
 
29
31
  name = colorize_payload_name(name, payload[:name])
30
- sql = color(sql, sql_color(sql), true)
32
+ sql = if ::Rails.version < "7.1"
33
+ color(sql, sql_color(sql), true)
34
+ else
35
+ color(sql, sql_color(sql), bold: true)
36
+ end
31
37
 
32
38
  debug " #{name} #{sql}#{binds}#{shard}"
33
39
  end
@@ -29,7 +29,11 @@ module Switchman
29
29
  db_name_hash = Zlib.crc32(Shard.current.name)
30
30
  shard_name_hash = ::ActiveRecord::Migrator::MIGRATOR_SALT * db_name_hash
31
31
  # Store in internalmetadata to allow other tools to be able to lock out migrations
32
- ::ActiveRecord::InternalMetadata[:migrator_advisory_lock_id] = shard_name_hash
32
+ if ::Rails.version < "7.1"
33
+ ::ActiveRecord::InternalMetadata[:migrator_advisory_lock_id] = shard_name_hash
34
+ else
35
+ ::ActiveRecord::InternalMetadata.new(connection)[:migrator_advisory_lock_id] = shard_name_hash
36
+ end
33
37
  shard_name_hash
34
38
  end
35
39
 
@@ -48,17 +52,30 @@ module Switchman
48
52
  module MigrationContext
49
53
  def migrate(...)
50
54
  connection = ::ActiveRecord::Base.connection
51
- connection_pool = ::ActiveRecord::Base.connection_pool
52
- previous_schema_cache = connection_pool.get_schema_cache(connection)
53
- temporary_schema_cache = ::ActiveRecord::ConnectionAdapters::SchemaCache.new(connection)
55
+ schema_cache_holder = ::ActiveRecord::Base.connection_pool
56
+ schema_cache_holder = schema_cache_holder.schema_reflection if ::Rails.version >= "7.1"
57
+ previous_schema_cache = if ::Rails.version < "7.1"
58
+ schema_cache_holder.get_schema_cache(connection)
59
+ else
60
+ schema_cache_holder.instance_variable_get(:@cache)
61
+ end
62
+
63
+ if ::Rails.version < "7.1"
64
+ temporary_schema_cache = ::ActiveRecord::ConnectionAdapters::SchemaCache.new(connection)
65
+
66
+ reset_column_information
67
+ schema_cache_holder.set_schema_cache(temporary_schema_cache)
68
+ else
69
+ schema_cache_holder.instance_variable_get(:@cache)
54
70
 
55
- reset_column_information
56
- connection_pool.set_schema_cache(temporary_schema_cache)
71
+ reset_column_information
72
+ schema_cache_holder.clear!
73
+ end
57
74
 
58
75
  begin
59
76
  super(...)
60
77
  ensure
61
- connection_pool.set_schema_cache(previous_schema_cache)
78
+ schema_cache_holder.set_schema_cache(previous_schema_cache)
62
79
  reset_column_information
63
80
  end
64
81
  end
@@ -34,6 +34,10 @@ module Switchman
34
34
  # When a shadow record is reloaded the real record is returned. So
35
35
  # we need to ensure the loaded_from_shard is set correctly after a reload.
36
36
  @loaded_from_shard = @shard
37
+ if @readonly_from_shadow
38
+ @readonly_from_shadow = false
39
+ @readonly = false
40
+ end
37
41
  res
38
42
  end
39
43
 
@@ -5,28 +5,57 @@ module Switchman
5
5
  module QueryCache
6
6
  private
7
7
 
8
- def cache_sql(sql, name, binds)
9
- # have to include the shard id in the cache key because of switching dbs on the same connection
10
- sql = "#{shard.id}::#{sql}"
11
- @lock.synchronize do
12
- result =
13
- if query_cache[sql].key?(binds)
14
- args = {
15
- sql: sql,
16
- binds: binds,
17
- name: name,
18
- connection_id: object_id,
19
- cached: true,
20
- type_casted_binds: -> { type_casted_binds(binds) }
21
- }
22
- ::ActiveSupport::Notifications.instrument(
23
- "sql.active_record",
24
- args
25
- )
26
- query_cache[sql][binds]
8
+ if ::Rails.version < "7.1"
9
+ def cache_sql(sql, name, binds)
10
+ # have to include the shard id in the cache key because of switching dbs on the same connection
11
+ sql = "#{shard.id}::#{sql}"
12
+ @lock.synchronize do
13
+ result =
14
+ if query_cache[sql].key?(binds)
15
+ args = {
16
+ sql: sql,
17
+ binds: binds,
18
+ name: name,
19
+ connection_id: object_id,
20
+ cached: true,
21
+ type_casted_binds: -> { type_casted_binds(binds) }
22
+ }
23
+ ::ActiveSupport::Notifications.instrument(
24
+ "sql.active_record",
25
+ args
26
+ )
27
+ query_cache[sql][binds]
28
+ else
29
+ query_cache[sql][binds] = yield
30
+ end
31
+ result.dup
32
+ end
33
+ end
34
+ else
35
+ def cache_sql(sql, name, binds)
36
+ # have to include the shard id in the cache key because of switching dbs on the same connection
37
+ sql = "#{shard.id}::#{sql}"
38
+ key = binds.empty? ? sql : [sql, binds]
39
+ result = nil
40
+ hit = false
41
+
42
+ @lock.synchronize do
43
+ if (result = @query_cache.delete(key))
44
+ hit = true
45
+ @query_cache[key] = result
27
46
  else
28
- query_cache[sql][binds] = yield
47
+ result = @query_cache[key] = yield
48
+ @query_cache.shift if @query_cache_max_size && @query_cache.size > @query_cache_max_size
29
49
  end
50
+ end
51
+
52
+ if hit
53
+ ::ActiveSupport::Notifications.instrument(
54
+ "sql.active_record",
55
+ cache_notification_info(sql, name, binds)
56
+ )
57
+ end
58
+
30
59
  result.dup
31
60
  end
32
61
  end
@@ -175,7 +175,7 @@ module Switchman
175
175
  end
176
176
 
177
177
  def sharded_foreign_key?(relation, column)
178
- models_for_table(relation.table_name).any? { |m| m.sharded_column?(column) }
178
+ models_for_table(relation.name).any? { |m| m.sharded_column?(column) }
179
179
  end
180
180
 
181
181
  def sharded_primary_key?(relation, column)
@@ -187,7 +187,7 @@ module Switchman
187
187
 
188
188
  def source_shard_for_foreign_key(relation, column)
189
189
  reflection = nil
190
- models_for_table(relation.table_name).each do |model|
190
+ models_for_table(relation.name).each do |model|
191
191
  reflection = model.send(:reflection_for_integer_attribute, column)
192
192
  break if reflection
193
193
  end
@@ -14,21 +14,28 @@ module Switchman
14
14
  # Code adapted from the code in rails proper
15
15
  @connection_subscriber =
16
16
  ::ActiveSupport::Notifications.subscribe("!connection.active_record") do |_, _, _, _, payload|
17
- spec_name = payload[:spec_name] if payload.key?(:spec_name)
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
18
22
  shard = payload[:shard] if payload.key?(:shard)
19
- setup_shared_connection_pool
20
23
 
21
24
  if spec_name && !FORBIDDEN_DB_ENVS.include?(shard)
22
25
  begin
23
26
  connection = ::ActiveRecord::Base.connection_handler.retrieve_connection(spec_name, shard: shard)
27
+ connection.connect! if ::Rails.version >= "7.1" # eagerly validate the connection
24
28
  rescue ::ActiveRecord::ConnectionNotEstablished, ::ActiveRecord::NoDatabaseError
25
29
  connection = nil
26
30
  end
27
31
 
28
- if connection && !@fixture_connections.include?(connection)
29
- connection.begin_transaction joinable: false, _lazy: false
30
- connection.pool.lock_thread = true if lock_threads
31
- @fixture_connections << connection
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
38
+ end
32
39
  end
33
40
  end
34
41
  end
@@ -37,7 +44,7 @@ module Switchman
37
44
  def enlist_fixture_connections
38
45
  setup_shared_connection_pool
39
46
 
40
- ::ActiveRecord::Base.connection_handler.connection_pool_list.reject do |cp|
47
+ ::ActiveRecord::Base.connection_handler.connection_pool_list(:primary).reject do |cp|
41
48
  FORBIDDEN_DB_ENVS.include?(cp.db_config.env_name.to_sym)
42
49
  end.map(&:connection)
43
50
  end
@@ -24,27 +24,29 @@ module Switchman
24
24
  collector << quote_local_table_name(join_name) << "." << quote_column_name(o.name)
25
25
  end
26
26
 
27
- def visit_Arel_Nodes_HomogeneousIn(o, collector)
28
- collector.preparable = false
27
+ if ::Rails.version < "7.1"
28
+ def visit_Arel_Nodes_HomogeneousIn(o, collector)
29
+ collector.preparable = false
29
30
 
30
- collector << quote_local_table_name(o.table_name) << "." << quote_column_name(o.column_name)
31
+ collector << quote_local_table_name(o.table_name) << "." << quote_column_name(o.column_name)
31
32
 
32
- collector << if o.type == :in
33
- " IN ("
34
- else
35
- " NOT IN ("
36
- end
33
+ collector << if o.type == :in
34
+ " IN ("
35
+ else
36
+ " NOT IN ("
37
+ end
37
38
 
38
- values = o.casted_values
39
+ values = o.casted_values
39
40
 
40
- if values.empty?
41
- collector << @connection.quote(nil)
42
- else
43
- collector.add_binds(values, o.proc_for_binds, &bind_block)
44
- end
41
+ if values.empty?
42
+ collector << @connection.quote(nil)
43
+ else
44
+ collector.add_binds(values, o.proc_for_binds, &bind_block)
45
+ end
45
46
 
46
- collector << ")"
47
- collector
47
+ collector << ")"
48
+ collector
49
+ end
48
50
  end
49
51
 
50
52
  # rubocop:enable Naming/MethodName
@@ -228,7 +228,11 @@ module Switchman
228
228
  unless schema == false
229
229
  shard.activate do
230
230
  ::ActiveRecord::Base.connection.transaction(requires_new: true) do
231
- ::ActiveRecord::Base.connection.migration_context.migrate
231
+ if ::Rails.version < "7.1"
232
+ ::ActiveRecord::Base.connection.migration_context.migrate
233
+ else
234
+ ::ActiveRecord::MigrationContext.new(::ActiveRecord::Migrator.migrations_paths).migrate
235
+ end
232
236
  end
233
237
 
234
238
  ::ActiveRecord::Base.descendants.reject do |m|
@@ -5,7 +5,7 @@ module Switchman
5
5
  isolate_namespace Switchman
6
6
 
7
7
  # enable Rails 6.1 style connection handling
8
- config.active_record.legacy_connection_handling = false
8
+ config.active_record.legacy_connection_handling = false if ::Rails.version < "7.1"
9
9
  config.active_record.writing_role = :primary
10
10
 
11
11
  ::GuardRail.singleton_class.prepend(GuardRail::ClassMethods)
@@ -60,6 +60,9 @@ module Switchman
60
60
  )
61
61
  end
62
62
  ::ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend(ActiveRecord::AbstractAdapter)
63
+ unless ::Rails.version < "7.1"
64
+ ::ActiveRecord::ConnectionAdapters::ConnectionHandler.prepend(ActiveRecord::ConnectionHandler)
65
+ end
63
66
  ::ActiveRecord::ConnectionAdapters::ConnectionPool.prepend(ActiveRecord::ConnectionPool)
64
67
  ::ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend(ActiveRecord::QueryCache)
65
68
  ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(ActiveRecord::PostgreSQLAdapter)
@@ -166,7 +166,11 @@ module Switchman
166
166
  # clear connections prior to forking (no more queries will be executed in the parent,
167
167
  # and we want them gone so that we don't accidentally use them post-fork doing something
168
168
  # silly like dealloc'ing prepared statements)
169
- ::ActiveRecord::Base.clear_all_connections!
169
+ if ::Rails.version < "7.1"
170
+ ::ActiveRecord::Base.clear_all_connections!(nil)
171
+ else
172
+ ::ActiveRecord::Base.connection_handler.clear_all_connections!(:all)
173
+ end
170
174
 
171
175
  parent_process_name = sanitized_process_title
172
176
  ret = ::Parallel.map(scopes, in_processes: (scopes.length > 1) ? parallel : 0) do |server, subscope|
@@ -258,7 +262,7 @@ module Switchman
258
262
  else
259
263
  shard = partition_object.shard
260
264
  end
261
- when Integer, /^\d+$/, /^(\d+)~(\d+)$/
265
+ when Integer, /\A\d+\Z/, /\A(\d+)~(\d+)\Z/
262
266
  local_id, shard = Shard.local_id_for(partition_object)
263
267
  local_id ||= partition_object
264
268
  object = local_id unless partition_proc
@@ -300,14 +304,14 @@ module Switchman
300
304
  case any_id
301
305
  when ::ActiveRecord::Base
302
306
  any_id.id
303
- when /^(\d+)~(-?\d+)$/
307
+ when /\A(\d+)~(-?\d+)\Z/
304
308
  local_id = $2.to_i
305
309
  signed_id_operation(local_id) do |id|
306
310
  return nil if id > IDS_PER_SHARD
307
311
 
308
312
  ($1.to_i * IDS_PER_SHARD) + id
309
313
  end
310
- when Integer, /^-?\d+$/
314
+ when Integer, /\A-?\d+\Z/
311
315
  any_id.to_i
312
316
  end
313
317
  end
@@ -410,7 +414,10 @@ module Switchman
410
414
  end
411
415
  end
412
416
 
417
+ # this resets the default shard on rails 7.1+, but we want to preserve it
418
+ shard_was = klass.default_shard
413
419
  klass.connects_to shards: connects_to_hash
420
+ klass.default_shard = shard_was
414
421
  end
415
422
  end
416
423
 
@@ -519,6 +526,10 @@ module Switchman
519
526
  id
520
527
  end
521
528
 
529
+ def original_id_value
530
+ id
531
+ end
532
+
522
533
  def activate(*classes, &block)
523
534
  shards = hashify_classes(classes)
524
535
  Shard.activate(shards, &block)
@@ -19,7 +19,7 @@ module Switchman
19
19
  end
20
20
 
21
21
  server1 = Shard.default.database_server
22
- server2 = DatabaseServer.create(Shard.default.database_server.config.merge(server2: true))
22
+ server2 = DatabaseServer.create(Shard.default.database_server.config.merge(server2: true, schema_dump: false))
23
23
 
24
24
  if server1 == Shard.default.database_server && server1.config[:shard1] && server1.config[:shard2]
25
25
  # look for the shards in the db already
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Switchman
4
- VERSION = "3.5.11"
4
+ VERSION = "3.5.13"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: switchman
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.5.11
4
+ version: 3.5.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cody Cutrer
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-10-02 00:00:00.000000000 Z
13
+ date: 2023-10-05 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: 6.1.4
22
22
  - - "<"
23
23
  - !ruby/object:Gem::Version
24
- version: '7.1'
24
+ version: '7.2'
25
25
  type: :runtime
26
26
  prerelease: false
27
27
  version_requirements: !ruby/object:Gem::Requirement
@@ -31,7 +31,7 @@ dependencies:
31
31
  version: 6.1.4
32
32
  - - "<"
33
33
  - !ruby/object:Gem::Version
34
- version: '7.1'
34
+ version: '7.2'
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: guardrail
37
37
  requirement: !ruby/object:Gem::Requirement
@@ -69,7 +69,7 @@ dependencies:
69
69
  version: '6.1'
70
70
  - - "<"
71
71
  - !ruby/object:Gem::Version
72
- version: '7.1'
72
+ version: '7.2'
73
73
  type: :runtime
74
74
  prerelease: false
75
75
  version_requirements: !ruby/object:Gem::Requirement
@@ -79,21 +79,21 @@ dependencies:
79
79
  version: '6.1'
80
80
  - - "<"
81
81
  - !ruby/object:Gem::Version
82
- version: '7.1'
82
+ version: '7.2'
83
83
  - !ruby/object:Gem::Dependency
84
- name: byebug
84
+ name: debug
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '0'
89
+ version: '1.8'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ">="
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '0'
96
+ version: '1.8'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: pg
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -108,20 +108,6 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '1.2'
111
- - !ruby/object:Gem::Dependency
112
- name: pry
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
111
  - !ruby/object:Gem::Dependency
126
112
  name: rake
127
113
  requirement: !ruby/object:Gem::Requirement
@@ -255,6 +241,7 @@ files:
255
241
  - lib/switchman/active_record/attribute_methods.rb
256
242
  - lib/switchman/active_record/base.rb
257
243
  - lib/switchman/active_record/calculations.rb
244
+ - lib/switchman/active_record/connection_handler.rb
258
245
  - lib/switchman/active_record/connection_pool.rb
259
246
  - lib/switchman/active_record/database_configurations.rb
260
247
  - lib/switchman/active_record/database_configurations/database_config.rb