Created
September 13, 2021 22:51
-
-
Save ixti/1d3325b9688e87d2b3f7ae1e48d1bda5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
module ActiveRecord | |
module Schema | |
class Context | |
class Table | |
class Index | |
attr_reader :columns, :options | |
def initialize(columns, **options) | |
@columns = columns | |
@options = options | |
end | |
end | |
attr_reader :name | |
def initialize(name, **, &block) | |
@name = name | |
@indices = [] | |
instance_eval(&block) | |
end | |
def index(columns, **options) | |
@indices << Index.new(columns, **options) | |
end | |
def redundant_indices | |
Enumerator.new do |y| | |
longest_index = nil | |
@indices.sort_by(&:columns).reverse_each do |index| | |
next longest_index = index unless longest_index | |
next longest_index = index unless index.columns == (index.columns & longest_index.columns) | |
y.yield(index, longest_index) | |
end | |
end | |
end | |
%i[bigint boolean date datetime json integer string text].each do |dsl| | |
define_method(dsl) do |*, **| | |
# do nothing | |
end | |
end | |
end | |
def initialize(&block) | |
@tables = [] | |
instance_eval(&block) | |
end | |
def create_table(name, **, &block) | |
@tables << Table.new(name, &block) | |
end | |
def print_suggestions | |
@tables.each do |t| | |
memo = Hash.new { |h, k| h[k] = [] } | |
t.redundant_indices.each { |index, covered_by| memo[covered_by] << index } | |
next if memo.empty? | |
memo.each do |longer_index, redundant_indices| | |
puts "# covered by: #{longer_index.options[:name]}" | |
redundant_indices.each do |index| | |
puts "remove_index :#{t.name}, %i[#{index.columns.join ' '}]" | |
end | |
end | |
end | |
end | |
end | |
def self.define(**, &block) | |
Context.new(&block).print_suggestions | |
end | |
end | |
end | |
require_relative "db/schema" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment