Class: ActiveRecord::OverflowSignalizer

Inherits:
Object
  • Object
show all
Defined in:
lib/activerecord/overflow_signalizer.rb,
lib/activerecord/overflow_signalizer/version.rb

Defined Under Namespace

Classes: Overflow, UnsupportedType

Constant Summary collapse

DAY =
24 * 60 * 60
DEFAULT_AVG =
100_000
MAX_VALUE =
{
  'integer' => 2_147_483_647,
  'bigint' => 9_223_372_036_854_775_807
}.freeze
VERSION =
'2.0.3'.freeze

Instance Method Summary collapse

Constructor Details

#initialize(logger: nil, models: nil, days_count: 60, signalizer: nil) ⇒ OverflowSignalizer

Returns a new instance of OverflowSignalizer.



17
18
19
20
21
22
# File 'lib/activerecord/overflow_signalizer.rb', line 17

def initialize(logger: nil, models: nil, days_count: 60, signalizer: nil)
  @logger = logger || ActiveRecord::Base.logger
  @models = models || ActiveRecord::Base.descendants
  @days_count = days_count
  @signalizer = signalizer
end

Instance Method Details

#analyseObject



49
50
51
52
53
# File 'lib/activerecord/overflow_signalizer.rb', line 49

def analyse
  analyse!
rescue Overflow => e
  signalize(e.message)
end

#analyse!Object

Raises:



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/activerecord/overflow_signalizer.rb', line 24

def analyse!
  overflowed_tables = []
  @models.group_by(&:table_name).each do |table, models|
    model = models.first
    next if model.abstract_class? || model.last.nil?
    pk = model.columns.select { |c| c.name == model.primary_key }.first
    max = MAX_VALUE.fetch(pk.sql_type) do |type|
      @logger.warn "Model #{model} has primary_key #{model.primary_key} with unsupported type #{type}"
      nil
    end
    next unless max
    if overflow_soon?(max, model)
      if (remaining = max - model.maximum(pk.name)) == 0
        @logger.warn("Table #{table} field #{pk.name} has overflown!")
      else
        @logger.warn("Table #{table} field #{pk.name} will overflow after #{remaining} records!")
      end
      overflowed_tables << [table, model.last.public_send(pk.name), max]
    else
      @logger.info("Table #{table} field #{pk.name} is not going to overflow in the next #{@days_count} days.")
    end
  end
  raise Overflow, overflow_message(overflowed_tables) if overflowed_tables.any?
end