Skip to content

Commit

Permalink
Merge pull request #239 from toydestroyer/allow-custom-checkers
Browse files Browse the repository at this point in the history
Allow custom checkers
  • Loading branch information
djezzzl authored Dec 25, 2024
2 parents 4e6aaac + 45be8e2 commit 1940867
Show file tree
Hide file tree
Showing 13 changed files with 48 additions and 92 deletions.
23 changes: 14 additions & 9 deletions lib/database_consistency.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# frozen_string_literal: true

require 'active_record'
require 'active_support/inflector'

ActiveSupport::Inflector.inflections do |inflect|
inflect.irregular 'index', 'indexes'
end

require 'database_consistency/version'
require 'database_consistency/helper'
Expand Down Expand Up @@ -60,6 +65,15 @@
require 'database_consistency/databases/types/base'
require 'database_consistency/databases/types/sqlite'

require 'database_consistency/processors/base_processor'
require 'database_consistency/processors/enums_processor'
require 'database_consistency/processors/associations_processor'
require 'database_consistency/processors/validators_processor'
require 'database_consistency/processors/columns_processor'
require 'database_consistency/processors/validators_fractions_processor'
require 'database_consistency/processors/indexes_processor'
require 'database_consistency/processors/models_processor'

require 'database_consistency/checkers/base_checker'

require 'database_consistency/checkers/enum_checkers/enum_checker'
Expand Down Expand Up @@ -95,15 +109,6 @@
require 'database_consistency/checkers/index_checkers/redundant_index_checker'
require 'database_consistency/checkers/index_checkers/redundant_unique_index_checker'

require 'database_consistency/processors/base_processor'
require 'database_consistency/processors/enums_processor'
require 'database_consistency/processors/associations_processor'
require 'database_consistency/processors/validators_processor'
require 'database_consistency/processors/columns_processor'
require 'database_consistency/processors/validators_fractions_processor'
require 'database_consistency/processors/indexes_processor'
require 'database_consistency/processors/models_processor'

# The root module
module DatabaseConsistency
class << self
Expand Down
12 changes: 11 additions & 1 deletion lib/database_consistency/checkers/base_checker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,19 @@ def self.enabled?(configuration)
configuration.enabled?('DatabaseConsistencyCheckers', checker_name)
end

def self.inherited(subclass)
super

return if subclass.superclass.name == 'DatabaseConsistency::Checkers::BaseChecker'

processor_prefix = subclass.superclass.name.demodulize.delete_suffix('Checker').pluralize
processor = "DatabaseConsistency::Processors::#{processor_prefix}Processor".constantize
processor.checkers << subclass
end

# @return [String]
def self.checker_name
@checker_name ||= name.split('::').last
@checker_name ||= name.demodulize
end

# @param [Boolean] catch_errors
Expand Down
10 changes: 10 additions & 0 deletions lib/database_consistency/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ def initialize(file_paths = DEFAULT_PATH)
end
extract_configurations(existing_paths)
end

load_custom_checkers
end

def debug?
Expand Down Expand Up @@ -123,5 +125,13 @@ def log_level
settings && settings['log_level']
end
end

def load_custom_checkers
return unless configuration.key?('require') && configuration['require'].is_a?(Array)

configuration['require'].each do |path|
require path
end
end
end
end
8 changes: 0 additions & 8 deletions lib/database_consistency/processors/associations_processor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,6 @@ module DatabaseConsistency
module Processors
# The class to process associations
class AssociationsProcessor < BaseProcessor
CHECKERS = [
Checkers::MissingIndexChecker,
Checkers::ForeignKeyChecker,
Checkers::ForeignKeyTypeChecker,
Checkers::ForeignKeyCascadeChecker,
Checkers::MissingAssociationClassChecker
].freeze

private

def check # rubocop:disable Metrics/MethodLength
Expand Down
16 changes: 6 additions & 10 deletions lib/database_consistency/processors/base_processor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,17 @@ module DatabaseConsistency
# The module for processors
module Processors
def self.reports(configuration)
[
ColumnsProcessor,
ValidatorsProcessor,
AssociationsProcessor,
ValidatorsFractionsProcessor,
IndexesProcessor,
EnumsProcessor,
ModelsProcessor
].flat_map do |processor|
BaseProcessor.descendants.flat_map do |processor|
processor.new(configuration).reports
end
end

# The base class for processors
class BaseProcessor
def self.checkers
@checkers ||= Set.new
end

attr_reader :configuration

# @param [DatabaseConsistency::Configuration] configuration
Expand All @@ -38,7 +34,7 @@ def reports(catch_errors: true)

# @return [Array<Class>]
def enabled_checkers
self.class::CHECKERS.select { |checker| checker.enabled?(configuration) }
self.class.checkers.select { |checker| checker.enabled?(configuration) }
end

private
Expand Down
9 changes: 0 additions & 9 deletions lib/database_consistency/processors/columns_processor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,6 @@ module DatabaseConsistency
module Processors
# The class to process columns
class ColumnsProcessor < BaseProcessor
CHECKERS = [
Checkers::NullConstraintChecker,
Checkers::LengthConstraintChecker,
Checkers::PrimaryKeyTypeChecker,
Checkers::EnumValueChecker,
Checkers::ThreeStateBooleanChecker,
Checkers::ImplicitOrderingChecker
].freeze

private

def check # rubocop:disable Metrics/MethodLength
Expand Down
4 changes: 0 additions & 4 deletions lib/database_consistency/processors/enums_processor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ module DatabaseConsistency
module Processors
# The class to process enums
class EnumsProcessor < BaseProcessor
CHECKERS = [
Checkers::EnumTypeChecker
].freeze

private

def check # rubocop:disable Metrics/MethodLength
Expand Down
6 changes: 0 additions & 6 deletions lib/database_consistency/processors/indexes_processor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@ module DatabaseConsistency
module Processors
# The class to process indexes
class IndexesProcessor < BaseProcessor
CHECKERS = [
Checkers::UniqueIndexChecker,
Checkers::RedundantIndexChecker,
Checkers::RedundantUniqueIndexChecker
].freeze

private

def check # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
Expand Down
4 changes: 0 additions & 4 deletions lib/database_consistency/processors/models_processor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ module DatabaseConsistency
module Processors
# The class to process models
class ModelsProcessor < BaseProcessor
CHECKERS = [
Checkers::MissingTableChecker
].freeze

private

def check
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ module DatabaseConsistency
module Processors
# The class to process validators
class ValidatorsFractionsProcessor < BaseProcessor
CHECKERS = [
Checkers::ColumnPresenceChecker
].freeze

private

# @return [Array<Hash>]
Expand Down
5 changes: 0 additions & 5 deletions lib/database_consistency/processors/validators_processor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@ module DatabaseConsistency
module Processors
# The class to process validators
class ValidatorsProcessor < BaseProcessor
CHECKERS = [
Checkers::MissingUniqueIndexChecker,
Checkers::CaseSensitiveUniqueValidationChecker
].freeze

private

# @return [Array<Hash>]
Expand Down
37 changes: 6 additions & 31 deletions lib/database_consistency/writers/simple_writer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,6 @@ module DatabaseConsistency
module Writers
# The simplest formatter
class SimpleWriter < BaseWriter
SLUG_TO_WRITER = {
association_foreign_type_missing_null_constraint: Simple::AssociationForeignTypeMissingNullConstraint,
association_missing_index: Simple::AssociationMissingIndex,
association_missing_null_constraint: Simple::AssociationMissingNullConstraint,
enum_values_inconsistent_with_ar_enum: Simple::EnumValuesInconsistentWithArEnum,
enum_values_inconsistent_with_inclusion: Simple::EnumValuesInconsistentWithInclusion,
has_one_missing_unique_index: Simple::HasOneMissingUniqueIndex,
implicit_order_column_missing: Simple::ImplicitOrderColumnMissing,
inconsistent_enum_type: Simple::InconsistentEnumType,
inconsistent_types: Simple::InconsistentTypes,
length_validator_greater_limit: Simple::LengthValidatorGreaterLimit,
length_validator_lower_limit: Simple::LengthValidatorLowerLimit,
length_validator_missing: Simple::LengthValidatorMissing,
missing_association_class: Simple::MissingAssociationClass,
missing_foreign_key: Simple::MissingForeignKey,
missing_foreign_key_cascade: Simple::MissingForeignKeyCascade,
missing_table: Simple::MissingTable,
missing_unique_index: Simple::MissingUniqueIndex,
missing_uniqueness_validation: Simple::MissingUniquenessValidation,
null_constraint_association_misses_validator: Simple::NullConstraintAssociationMissesValidator,
null_constraint_misses_validator: Simple::NullConstraintMissesValidator,
null_constraint_missing: Simple::NullConstraintMissing,
possible_null: Simple::PossibleNull,
redundant_case_insensitive_option: Simple::RedundantCaseInsensitiveOption,
redundant_index: Simple::RedundantIndex,
redundant_unique_index: Simple::RedundantUniqueIndex,
small_primary_key: Simple::SmallPrimaryKey,
three_state_boolean: Simple::ThreeStateBoolean
}.freeze

def write
results.select(&method(:write?))
.map(&method(:writer))
Expand All @@ -58,7 +28,12 @@ def write?(report)
end

def writer(report)
klass = SLUG_TO_WRITER[report.error_slug] || Simple::DefaultMessage
klass = begin
"DatabaseConsistency::Writers::Simple::#{report.error_slug.to_s.classify}".constantize
rescue NameError
Simple::DefaultMessage
end

klass.new(report, config: config)
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/checkers/unique_index_checker_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
let(:model) { klass }
let(:index) { ActiveRecord::Base.connection.indexes(klass.table_name).first }

let(:checker_name) { described_class.to_s.split('::').last }
let(:checker_name) { described_class.name.demodulize }
let(:index_name) { 'index_name' }

context 'when unique index is based on association' do
Expand Down

0 comments on commit 1940867

Please sign in to comment.