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
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