Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow custom checkers #239

Merged
merged 2 commits into from
Dec 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading