2019-09-11 12:23:42 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
module Gitlab
|
|
|
|
module Database
|
|
|
|
# Checks which `ignored_columns` can be safely removed by scanning
|
|
|
|
# the current schema for all `ApplicationRecord` descendants.
|
|
|
|
class ObsoleteIgnoredColumns
|
|
|
|
def initialize(base = ApplicationRecord)
|
|
|
|
@base = base
|
|
|
|
end
|
|
|
|
|
|
|
|
def execute
|
|
|
|
@base.descendants.map do |klass|
|
|
|
|
next if klass.abstract_class?
|
|
|
|
|
|
|
|
safe_to_remove = ignored_columns_safe_to_remove_for(klass)
|
|
|
|
next if safe_to_remove.empty?
|
|
|
|
|
|
|
|
[klass.name, safe_to_remove]
|
|
|
|
end.compact.sort_by(&:first)
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def ignored_columns_safe_to_remove_for(klass)
|
2019-12-01 01:06:11 -05:00
|
|
|
ignores = ignored_and_not_present(klass).each_with_object({}) do |col, h|
|
|
|
|
h[col] = klass.ignored_columns_details[col.to_sym]
|
|
|
|
end
|
|
|
|
|
|
|
|
ignores.select { |_, i| i&.safe_to_remove? }
|
|
|
|
end
|
2019-09-11 12:23:42 -04:00
|
|
|
|
2019-12-01 01:06:11 -05:00
|
|
|
def ignored_and_not_present(klass)
|
|
|
|
ignored = klass.ignored_columns.map(&:to_s)
|
2019-09-11 12:23:42 -04:00
|
|
|
return [] if ignored.empty?
|
|
|
|
|
|
|
|
schema = klass.connection.schema_cache.columns_hash(klass.table_name)
|
|
|
|
existing = schema.values.map(&:name)
|
|
|
|
|
|
|
|
used = ignored & existing
|
|
|
|
ignored - used
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|