database_consistency 0.8.10 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/database_consistency.rb +6 -0
- data/lib/database_consistency/checkers/association_checkers/foreign_key_type_checker.rb +1 -1
- data/lib/database_consistency/checkers/index_checkers/index_checker.rb +23 -0
- data/lib/database_consistency/checkers/index_checkers/redundant_index_checker.rb +55 -0
- data/lib/database_consistency/checkers/index_checkers/redundant_unique_index_checker.rb +55 -0
- data/lib/database_consistency/checkers/index_checkers/unique_index_checker.rb +47 -0
- data/lib/database_consistency/checkers/validator_checkers/missing_unique_index_checker.rb +4 -34
- data/lib/database_consistency/helper.rb +34 -0
- data/lib/database_consistency/processors/base_processor.rb +2 -1
- data/lib/database_consistency/processors/indexes_processor.rb +31 -0
- data/lib/database_consistency/templates/rails_defaults.yml +2 -0
- data/lib/database_consistency/version.rb +1 -1
- metadata +11 -6
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: f37408420931f459ea476d095f441e40256ea2279e07c21ad9d477c0781d5944
         | 
| 4 | 
            +
              data.tar.gz: b054877a7819333fab57dbe22786456d4a0328b462f9808561e470290b3ae6e7
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: c2e7a18dabde150f3f1f2ee144b6076e2c0fb944c9c128851379e86007f0aed056f1fb550cc19319b777767ffc165534939a680e248213473032054dfa8e2924
         | 
| 7 | 
            +
              data.tar.gz: f047ff2a3e5e41137a93f5c64e4a0288e74b0d687670e7eabe5b3656a675abf87df75586fd5a0988f25f26f993d20542addfd2d84b430dac7dd30025f2016415
         | 
    
        data/lib/database_consistency.rb
    CHANGED
    
    | @@ -33,11 +33,17 @@ require 'database_consistency/checkers/validator_checkers/missing_unique_index_c | |
| 33 33 | 
             
            require 'database_consistency/checkers/validators_fraction_checkers/validators_fraction_checker'
         | 
| 34 34 | 
             
            require 'database_consistency/checkers/validators_fraction_checkers/column_presence_checker'
         | 
| 35 35 |  | 
| 36 | 
            +
            require 'database_consistency/checkers/index_checkers/index_checker'
         | 
| 37 | 
            +
            require 'database_consistency/checkers/index_checkers/unique_index_checker'
         | 
| 38 | 
            +
            require 'database_consistency/checkers/index_checkers/redundant_index_checker'
         | 
| 39 | 
            +
            require 'database_consistency/checkers/index_checkers/redundant_unique_index_checker'
         | 
| 40 | 
            +
             | 
| 36 41 | 
             
            require 'database_consistency/processors/base_processor'
         | 
| 37 42 | 
             
            require 'database_consistency/processors/associations_processor'
         | 
| 38 43 | 
             
            require 'database_consistency/processors/validators_processor'
         | 
| 39 44 | 
             
            require 'database_consistency/processors/columns_processor'
         | 
| 40 45 | 
             
            require 'database_consistency/processors/validators_fractions_processor'
         | 
| 46 | 
            +
            require 'database_consistency/processors/indexes_processor'
         | 
| 41 47 |  | 
| 42 48 | 
             
            # The root module
         | 
| 43 49 | 
             
            module DatabaseConsistency
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module DatabaseConsistency
         | 
| 4 | 
            +
              module Checkers
         | 
| 5 | 
            +
                # The base class for table checkers
         | 
| 6 | 
            +
                class IndexChecker < BaseChecker
         | 
| 7 | 
            +
                  attr_reader :model, :index
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  def initialize(model, index)
         | 
| 10 | 
            +
                    @model = model
         | 
| 11 | 
            +
                    @index = index
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  def column_or_attribute_name
         | 
| 15 | 
            +
                    @column_or_attribute_name ||= index.name.to_s
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  def table_or_model_name
         | 
| 19 | 
            +
                    @table_or_model_name ||= model.name.to_s
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
            end
         | 
| @@ -0,0 +1,55 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module DatabaseConsistency
         | 
| 4 | 
            +
              module Checkers
         | 
| 5 | 
            +
                # This class checks redundant database indexes
         | 
| 6 | 
            +
                class RedundantIndexChecker < IndexChecker
         | 
| 7 | 
            +
                  # Message templates
         | 
| 8 | 
            +
                  REDUNDANT_INDEX = 'index is redundant as (%index) covers it'
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  private
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  # We skip check when:
         | 
| 13 | 
            +
                  #  - index is unique
         | 
| 14 | 
            +
                  def preconditions
         | 
| 15 | 
            +
                    !index.unique
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  # Table of possible statuses
         | 
| 19 | 
            +
                  # | validation | status |
         | 
| 20 | 
            +
                  # | ---------- | ------ |
         | 
| 21 | 
            +
                  # | provided   | ok     |
         | 
| 22 | 
            +
                  # | redundant  | fail   |
         | 
| 23 | 
            +
                  #
         | 
| 24 | 
            +
                  def check
         | 
| 25 | 
            +
                    if covered_by_index
         | 
| 26 | 
            +
                      report_template(:fail, render_message)
         | 
| 27 | 
            +
                    else
         | 
| 28 | 
            +
                      report_template(:ok)
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  def render_message
         | 
| 33 | 
            +
                    REDUNDANT_INDEX.sub('%index', covered_by_index.name)
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  def covered_by_index
         | 
| 37 | 
            +
                    @covered_by_index ||=
         | 
| 38 | 
            +
                      model.connection.indexes(model.table_name).find do |another_index|
         | 
| 39 | 
            +
                        next if index.name == another_index.name
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                        include_index_as_prefix?(another_index)
         | 
| 42 | 
            +
                      end
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  def include_index_as_prefix?(another_index)
         | 
| 46 | 
            +
                    another_index_columns = Helper.extract_index_columns(another_index.columns)
         | 
| 47 | 
            +
                    index_columns == another_index_columns.first(index_columns.size)
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  def index_columns
         | 
| 51 | 
            +
                    @index_columns ||= Helper.extract_index_columns(index.columns)
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
            end
         | 
| @@ -0,0 +1,55 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module DatabaseConsistency
         | 
| 4 | 
            +
              module Checkers
         | 
| 5 | 
            +
                # This class checks redundant database indexes
         | 
| 6 | 
            +
                class RedundantUniqueIndexChecker < IndexChecker
         | 
| 7 | 
            +
                  # Message templates
         | 
| 8 | 
            +
                  REDUNDANT_UNIQUE_INDEX = 'index uniqueness is redundant as (%index) covers it'
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  private
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  # We skip check when:
         | 
| 13 | 
            +
                  #  - index is not unique
         | 
| 14 | 
            +
                  def preconditions
         | 
| 15 | 
            +
                    index.unique
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  # Table of possible statuses
         | 
| 19 | 
            +
                  # | validation | status |
         | 
| 20 | 
            +
                  # | ---------- | ------ |
         | 
| 21 | 
            +
                  # | provided   | ok     |
         | 
| 22 | 
            +
                  # | redundant  | fail   |
         | 
| 23 | 
            +
                  #
         | 
| 24 | 
            +
                  def check
         | 
| 25 | 
            +
                    if covered_by_index
         | 
| 26 | 
            +
                      report_template(:fail, render_message)
         | 
| 27 | 
            +
                    else
         | 
| 28 | 
            +
                      report_template(:ok)
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  def render_message
         | 
| 33 | 
            +
                    REDUNDANT_UNIQUE_INDEX.sub('%index', covered_by_index.name)
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  def covered_by_index
         | 
| 37 | 
            +
                    @covered_by_index ||=
         | 
| 38 | 
            +
                      model.connection.indexes(model.table_name).find do |another_index|
         | 
| 39 | 
            +
                        next if index.name == another_index.name
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                        another_index.unique && contain_index?(another_index)
         | 
| 42 | 
            +
                      end
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  def contain_index?(another_index)
         | 
| 46 | 
            +
                    another_index_columns = Helper.extract_index_columns(another_index.columns)
         | 
| 47 | 
            +
                    index_columns & another_index_columns == another_index_columns
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  def index_columns
         | 
| 51 | 
            +
                    @index_columns ||= Helper.extract_index_columns(index.columns)
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
            end
         | 
| @@ -0,0 +1,47 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module DatabaseConsistency
         | 
| 4 | 
            +
              module Checkers
         | 
| 5 | 
            +
                # This class checks missing uniqueness validator
         | 
| 6 | 
            +
                class UniqueIndexChecker < IndexChecker
         | 
| 7 | 
            +
                  # Message templates
         | 
| 8 | 
            +
                  VALIDATOR_MISSING = 'index is unique in the database but do not have uniqueness validator'
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  private
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  # We skip check when:
         | 
| 13 | 
            +
                  #  - index is not unique
         | 
| 14 | 
            +
                  def preconditions
         | 
| 15 | 
            +
                    index.unique
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  # Table of possible statuses
         | 
| 19 | 
            +
                  # | validation | status |
         | 
| 20 | 
            +
                  # | ---------- | ------ |
         | 
| 21 | 
            +
                  # | provided   | ok     |
         | 
| 22 | 
            +
                  # | missing    | fail   |
         | 
| 23 | 
            +
                  #
         | 
| 24 | 
            +
                  def check
         | 
| 25 | 
            +
                    if valid?
         | 
| 26 | 
            +
                      report_template(:ok)
         | 
| 27 | 
            +
                    else
         | 
| 28 | 
            +
                      report_template(:fail, VALIDATOR_MISSING)
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  def valid?
         | 
| 33 | 
            +
                    uniqueness_validators = model.validators.select { |validator| validator.kind == :uniqueness }
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                    uniqueness_validators.any? do |validator|
         | 
| 36 | 
            +
                      validator.attributes.any? do |attribute|
         | 
| 37 | 
            +
                        sorted_index_columns == Helper.sorted_uniqueness_validator_columns(attribute, validator, model)
         | 
| 38 | 
            +
                      end
         | 
| 39 | 
            +
                    end
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  def sorted_index_columns
         | 
| 43 | 
            +
                    @sorted_index_columns ||= Helper.extract_index_columns(index.columns).sort
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
            end
         | 
| @@ -7,7 +7,7 @@ module DatabaseConsistency | |
| 7 7 | 
             
                  MISSING_INDEX = 'model should have proper unique index in the database'
         | 
| 8 8 |  | 
| 9 9 | 
             
                  def column_or_attribute_name
         | 
| 10 | 
            -
                    @column_or_attribute_name ||=  | 
| 10 | 
            +
                    @column_or_attribute_name ||= Helper.uniqueness_validator_columns(attribute, validator, model).join('+')
         | 
| 11 11 | 
             
                  end
         | 
| 12 12 |  | 
| 13 13 | 
             
                  private
         | 
| @@ -33,42 +33,12 @@ module DatabaseConsistency | |
| 33 33 |  | 
| 34 34 | 
             
                  def unique_index
         | 
| 35 35 | 
             
                    @unique_index ||= model.connection.indexes(model.table_name).find do |index|
         | 
| 36 | 
            -
                      index.unique && extract_index_columns(index.columns).sort ==  | 
| 36 | 
            +
                      index.unique && Helper.extract_index_columns(index.columns).sort == sorted_uniqueness_validator_columns
         | 
| 37 37 | 
             
                    end
         | 
| 38 38 | 
             
                  end
         | 
| 39 39 |  | 
| 40 | 
            -
                   | 
| 41 | 
            -
             | 
| 42 | 
            -
                    return index_columns unless index_columns.is_a?(String)
         | 
| 43 | 
            -
             | 
| 44 | 
            -
                    index_columns.split(',')
         | 
| 45 | 
            -
                                 .map(&:strip)
         | 
| 46 | 
            -
                                 .map { |str| str.gsub(/lower\(/i, 'lower(') }
         | 
| 47 | 
            -
                                 .map { |str| str.gsub(/\(([^)]+)\)::\w+/, '\1') }
         | 
| 48 | 
            -
                                 .map { |str| str.gsub(/'([^)]+)'::\w+/, '\1') }
         | 
| 49 | 
            -
                  end
         | 
| 50 | 
            -
             | 
| 51 | 
            -
                  def index_columns
         | 
| 52 | 
            -
                    @index_columns ||= ([wrapped_attribute_name] + scope_columns).map(&:to_s)
         | 
| 53 | 
            -
                  end
         | 
| 54 | 
            -
             | 
| 55 | 
            -
                  def scope_columns
         | 
| 56 | 
            -
                    @scope_columns ||= Array.wrap(validator.options[:scope]).map do |scope_item|
         | 
| 57 | 
            -
                      model._reflect_on_association(scope_item)&.foreign_key || scope_item
         | 
| 58 | 
            -
                    end
         | 
| 59 | 
            -
                  end
         | 
| 60 | 
            -
             | 
| 61 | 
            -
                  def sorted_index_columns
         | 
| 62 | 
            -
                    @sorted_index_columns ||= index_columns.sort
         | 
| 63 | 
            -
                  end
         | 
| 64 | 
            -
             | 
| 65 | 
            -
                  # @return [String]
         | 
| 66 | 
            -
                  def wrapped_attribute_name
         | 
| 67 | 
            -
                    if validator.options[:case_sensitive].nil? || validator.options[:case_sensitive]
         | 
| 68 | 
            -
                      attribute
         | 
| 69 | 
            -
                    else
         | 
| 70 | 
            -
                      "lower(#{attribute})"
         | 
| 71 | 
            -
                    end
         | 
| 40 | 
            +
                  def sorted_uniqueness_validator_columns
         | 
| 41 | 
            +
                    @sorted_uniqueness_validator_columns ||= Helper.sorted_uniqueness_validator_columns(attribute, validator, model)
         | 
| 72 42 | 
             
                  end
         | 
| 73 43 | 
             
                end
         | 
| 74 44 | 
             
              end
         | 
| @@ -34,5 +34,39 @@ module DatabaseConsistency | |
| 34 34 |  | 
| 35 35 | 
             
                  associations
         | 
| 36 36 | 
             
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                # @return [Array<String>]
         | 
| 39 | 
            +
                def extract_index_columns(index_columns)
         | 
| 40 | 
            +
                  return index_columns unless index_columns.is_a?(String)
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  index_columns.split(',')
         | 
| 43 | 
            +
                               .map(&:strip)
         | 
| 44 | 
            +
                               .map { |str| str.gsub(/lower\(/i, 'lower(') }
         | 
| 45 | 
            +
                               .map { |str| str.gsub(/\(([^)]+)\)::\w+/, '\1') }
         | 
| 46 | 
            +
                               .map { |str| str.gsub(/'([^)]+)'::\w+/, '\1') }
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                def sorted_uniqueness_validator_columns(attribute, validator, model)
         | 
| 50 | 
            +
                  uniqueness_validator_columns(attribute, validator, model).sort
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                def uniqueness_validator_columns(attribute, validator, model)
         | 
| 54 | 
            +
                  ([wrapped_attribute_name(attribute, validator)] + scope_columns(validator, model)).map(&:to_s)
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                def scope_columns(validator, model)
         | 
| 58 | 
            +
                  Array.wrap(validator.options[:scope]).map do |scope_item|
         | 
| 59 | 
            +
                    model._reflect_on_association(scope_item)&.foreign_key || scope_item
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                # @return [String]
         | 
| 64 | 
            +
                def wrapped_attribute_name(attribute, validator)
         | 
| 65 | 
            +
                  if validator.options[:case_sensitive].nil? || validator.options[:case_sensitive]
         | 
| 66 | 
            +
                    attribute
         | 
| 67 | 
            +
                  else
         | 
| 68 | 
            +
                    "lower(#{attribute})"
         | 
| 69 | 
            +
                  end
         | 
| 70 | 
            +
                end
         | 
| 37 71 | 
             
              end
         | 
| 38 72 | 
             
            end
         | 
| @@ -0,0 +1,31 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module DatabaseConsistency
         | 
| 4 | 
            +
              module Processors
         | 
| 5 | 
            +
                # The class to process indexes
         | 
| 6 | 
            +
                class IndexesProcessor < BaseProcessor
         | 
| 7 | 
            +
                  CHECKERS = [
         | 
| 8 | 
            +
                    Checkers::UniqueIndexChecker,
         | 
| 9 | 
            +
                    Checkers::RedundantIndexChecker,
         | 
| 10 | 
            +
                    Checkers::RedundantUniqueIndexChecker
         | 
| 11 | 
            +
                  ].freeze
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  private
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  def check # rubocop:disable Metrics/AbcSize
         | 
| 16 | 
            +
                    Helper.parent_models.flat_map do |model|
         | 
| 17 | 
            +
                      next unless configuration.enabled?(model.name.to_s)
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                      indexes = ActiveRecord::Base.connection.indexes(model.table_name)
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                      indexes.flat_map do |index|
         | 
| 22 | 
            +
                        enabled_checkers.map do |checker_class|
         | 
| 23 | 
            +
                          checker = checker_class.new(model, index)
         | 
| 24 | 
            +
                          checker.report_if_enabled?(configuration)
         | 
| 25 | 
            +
                        end
         | 
| 26 | 
            +
                      end
         | 
| 27 | 
            +
                    end.compact
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: database_consistency
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version:  | 
| 4 | 
            +
              version: 1.1.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Evgeniy Demin
         | 
| 8 | 
            -
            autorequire:
         | 
| 8 | 
            +
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2021-04-24 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: activerecord
         | 
| @@ -122,7 +122,7 @@ dependencies: | |
| 122 122 | 
             
                - - "~>"
         | 
| 123 123 | 
             
                  - !ruby/object:Gem::Version
         | 
| 124 124 | 
             
                    version: '1.3'
         | 
| 125 | 
            -
            description:
         | 
| 125 | 
            +
            description: 
         | 
| 126 126 | 
             
            email:
         | 
| 127 127 | 
             
            - lawliet.djez@gmail.com
         | 
| 128 128 | 
             
            executables:
         | 
| @@ -140,6 +140,10 @@ files: | |
| 140 140 | 
             
            - lib/database_consistency/checkers/column_checkers/length_constraint_checker.rb
         | 
| 141 141 | 
             
            - lib/database_consistency/checkers/column_checkers/null_constraint_checker.rb
         | 
| 142 142 | 
             
            - lib/database_consistency/checkers/column_checkers/primary_key_type_checker.rb
         | 
| 143 | 
            +
            - lib/database_consistency/checkers/index_checkers/index_checker.rb
         | 
| 144 | 
            +
            - lib/database_consistency/checkers/index_checkers/redundant_index_checker.rb
         | 
| 145 | 
            +
            - lib/database_consistency/checkers/index_checkers/redundant_unique_index_checker.rb
         | 
| 146 | 
            +
            - lib/database_consistency/checkers/index_checkers/unique_index_checker.rb
         | 
| 143 147 | 
             
            - lib/database_consistency/checkers/validator_checkers/belongs_to_presence_checker.rb
         | 
| 144 148 | 
             
            - lib/database_consistency/checkers/validator_checkers/missing_unique_index_checker.rb
         | 
| 145 149 | 
             
            - lib/database_consistency/checkers/validator_checkers/validator_checker.rb
         | 
| @@ -154,6 +158,7 @@ files: | |
| 154 158 | 
             
            - lib/database_consistency/processors/associations_processor.rb
         | 
| 155 159 | 
             
            - lib/database_consistency/processors/base_processor.rb
         | 
| 156 160 | 
             
            - lib/database_consistency/processors/columns_processor.rb
         | 
| 161 | 
            +
            - lib/database_consistency/processors/indexes_processor.rb
         | 
| 157 162 | 
             
            - lib/database_consistency/processors/validators_fractions_processor.rb
         | 
| 158 163 | 
             
            - lib/database_consistency/processors/validators_processor.rb
         | 
| 159 164 | 
             
            - lib/database_consistency/rescue_error.rb
         | 
| @@ -165,7 +170,7 @@ homepage: https://github.com/djezzzl/database_consistency | |
| 165 170 | 
             
            licenses:
         | 
| 166 171 | 
             
            - MIT
         | 
| 167 172 | 
             
            metadata: {}
         | 
| 168 | 
            -
            post_install_message:
         | 
| 173 | 
            +
            post_install_message: 
         | 
| 169 174 | 
             
            rdoc_options: []
         | 
| 170 175 | 
             
            require_paths:
         | 
| 171 176 | 
             
            - lib
         | 
| @@ -181,7 +186,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 181 186 | 
             
                  version: '0'
         | 
| 182 187 | 
             
            requirements: []
         | 
| 183 188 | 
             
            rubygems_version: 3.0.8
         | 
| 184 | 
            -
            signing_key:
         | 
| 189 | 
            +
            signing_key: 
         | 
| 185 190 | 
             
            specification_version: 4
         | 
| 186 191 | 
             
            summary: Provide an easy way to check the consistency of the database constraints
         | 
| 187 192 | 
             
              with the application validations.
         |