Add rake task `db:obsolete_ignored_columns`

Show a list of obsolete `ignored_columns`
This commit is contained in:
Peter Leitzen 2019-09-11 16:23:42 +00:00 committed by Douglas Barbosa Alexandre
parent 0abc902576
commit 50c647af51
4 changed files with 112 additions and 0 deletions

View File

@ -216,3 +216,13 @@ bundle exec rake routes
Since these take some time to create, it's often helpful to save the output to Since these take some time to create, it's often helpful to save the output to
a file for quick reference. a file for quick reference.
## Show obsolete `ignored_columns`
To see a list of all obsolete `ignored_columns` run:
```
bundle exec rake db:obsolete_ignored_columns
```
Feel free to remove their definitions from their `ignored_columns` definitions.

View File

@ -0,0 +1,38 @@
# 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)
ignored = klass.ignored_columns.map(&:to_s)
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

View File

@ -0,0 +1,21 @@
desc 'Show a list of obsolete `ignored_columns`'
task 'db:obsolete_ignored_columns' => :environment do
list = Gitlab::Database::ObsoleteIgnoredColumns.new.execute
if list.empty?
puts 'No obsolete `ignored_columns` found.'
else
puts 'The following `ignored_columns` are obsolete and can be removed:'
list.each do |name, ignored_columns|
puts "- #{name}: #{ignored_columns.join(', ')}"
end
puts <<~TEXT
WARNING: Removing columns is tricky because running GitLab processes may still be using the columns.
See also https://docs.gitlab.com/ee/development/what_requires_downtime.html#dropping-columns
TEXT
end
end

View File

@ -0,0 +1,43 @@
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::Database::ObsoleteIgnoredColumns do
module Testing
class MyBase < ApplicationRecord
end
class SomeAbstract < MyBase
self.abstract_class = true
self.table_name = 'projects'
self.ignored_columns += %i[unused]
end
class B < MyBase
self.table_name = 'issues'
self.ignored_columns += %i[id other]
end
class A < SomeAbstract
self.ignored_columns += %i[id also_unused]
end
class C < MyBase
self.table_name = 'users'
end
end
subject { described_class.new(Testing::MyBase) }
describe '#execute' do
it 'returns a list of class names and columns pairs' do
expect(subject.execute).to eq([
['Testing::A', %w(unused also_unused)],
['Testing::B', %w(other)]
])
end
end
end