Module: Switchman::ActiveRecord::Base::ClassMethods

Defined in:
lib/switchman/active_record/base.rb

Instance Method Summary collapse

Instance Method Details

#clear_query_caches_for_current_threadObject



105
106
107
108
109
110
111
112
113
114
# File 'lib/switchman/active_record/base.rb', line 105

def clear_query_caches_for_current_thread
  pools = if ::Rails.version < "7.1"
            ::ActiveRecord::Base.connection_handler.connection_pool_list
          else
            ::ActiveRecord::Base.connection_handler.connection_pool_list(:all)
          end
  pools.each do |pool|
    pool.connection(switch_shard: false).clear_query_cache if pool.active_connection?
  end
end

#connected_to_stackObject



138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/switchman/active_record/base.rb', line 138

def connected_to_stack
  has_own_stack = if ::Rails.version < "7.0"
                    Thread.current.thread_variable?(:ar_connected_to_stack)
                  else
                    ::ActiveSupport::IsolatedExecutionState.key?(:active_record_connected_to_stack)
                  end

  ret = super
  return ret if has_own_stack

  DatabaseServer.guard_servers
  ret
end

#connection_class_for_selfObject



194
195
196
# File 'lib/switchman/active_record/base.rb', line 194

def connection_class_for_self
  connection_classes
end

#current_role(without_overrides: false, target_shard: current_shard) ⇒ Object

significant change: Allow per-shard roles



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/switchman/active_record/base.rb', line 153

def current_role(without_overrides: false, target_shard: current_shard)
  return super() if without_overrides

  sharded_role = nil
  connected_to_stack.reverse_each do |hash|
    shard_role = hash.dig(:shard_roles, target_shard)
    unless shard_role &&
           (hash[:klasses].include?(::ActiveRecord::Base) || hash[:klasses].include?(connection_class_for_self))
      next
    end

    sharded_role = shard_role
    break
  end
  # Allow a shard-specific role to be reverted to regular inheritance
  return sharded_role if sharded_role && sharded_role != :_switchman_inherit

  super()
end

#current_shardObject

significant change: _don’t_ check if klasses.include?(Base) i.e. other sharded models don’t inherit the current shard of Base



175
176
177
178
179
180
181
# File 'lib/switchman/active_record/base.rb', line 175

def current_shard
  connected_to_stack.reverse_each do |hash|
    return hash[:shard] if hash[:shard] && hash[:klasses].include?(connection_class_for_self)
  end

  default_shard
end

#current_switchman_shardObject



183
184
185
186
187
188
189
190
191
# File 'lib/switchman/active_record/base.rb', line 183

def current_switchman_shard
  connected_to_stack.reverse_each do |hash|
    if hash[:switchman_shard] && hash[:klasses].include?(connection_class_for_self)
      return hash[:switchman_shard]
    end
  end

  Shard.default
end

#establish_connection(config_or_env = nil) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/switchman/active_record/base.rb', line 120

def establish_connection(config_or_env = nil)
  if config_or_env.is_a?(Symbol) && config_or_env != ::Rails.env.to_sym
    raise ArgumentError,
          "establish connection cannot be used on the non-current shard/role"
  end

  # Ensure we don't randomly surprise change the connection parms associated with a shard/role
  config_or_env = nil if config_or_env == ::Rails.env.to_sym

  config_or_env ||= if current_shard == ::Rails.env.to_sym && current_role == :primary
                      :primary
                    else
                      :"#{current_shard}/#{current_role}"
                    end

  super(config_or_env)
end

#find_ids_in_ranges(opts = {}, &block) ⇒ Object



9
10
11
12
# File 'lib/switchman/active_record/base.rb', line 9

def find_ids_in_ranges(opts = {}, &block)
  opts.reverse_merge!(loose: true)
  all.find_ids_in_ranges(opts, &block)
end

#integral_id?Boolean

Returns:

  • (Boolean)


20
21
22
23
# File 'lib/switchman/active_record/base.rb', line 20

def integral_id?
  @integral_id = columns_hash[primary_key]&.type == :integer if @integral_id.nil?
  @integral_id
end

#reset_column_informationObject



87
88
89
90
# File 'lib/switchman/active_record/base.rb', line 87

def reset_column_information
  @sharded_column_values = {}
  super
end

#role_overriden?(shard_id) ⇒ Boolean

Returns:

  • (Boolean)


116
117
118
# File 'lib/switchman/active_record/base.rb', line 116

def role_overriden?(shard_id)
  current_role(target_shard: shard_id) != current_role(without_overrides: true)
end

#sharded_modelObject



14
15
16
17
18
# File 'lib/switchman/active_record/base.rb', line 14

def sharded_model
  self.abstract_class = true

  Shard.send(:add_sharded_model, self)
end

#transactionObject



25
26
27
28
29
30
31
32
33
34
35
# File 'lib/switchman/active_record/base.rb', line 25

def transaction(**)
  if self != ::ActiveRecord::Base && current_scope
    current_scope.activate do
      db = Shard.current(connection_class_for_self).database_server
      db.unguard { super }
    end
  else
    db = Shard.current(connection_class_for_self).database_server
    db.unguard { super }
  end
end

#unscopedObject



92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/switchman/active_record/base.rb', line 92

def unscoped
  if block_given?
    super do
      current_scope.shard_value = nil
      yield
    end
  else
    result = super
    result.shard_value = nil
    result
  end
end