database_consistency 0.5.0 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5feffbf59ee35344cc1f96e796cd63adea0ca6aa6b01eb81cacbb5c166bd082b
4
- data.tar.gz: ac0bb8dbb583b572b785591f59bce8bebb307b267e07960707e72861e7d6b6ff
3
+ metadata.gz: 1528eadd95e4bdb9511b145d5d8584e4ebde5f9bf30b63de852e5d24fa5a79c5
4
+ data.tar.gz: 4b36f7adca734d72d611c12a846f800a507e5b56c4a32c524713b27a646f79e2
5
5
  SHA512:
6
- metadata.gz: 189c7967c87ebac15dfe0e68a98041423148a37596508360f87cbba295790754575aabef0cd4740e4d3c5b0bb6766eb62675920fcb01972f723d7ccfa166ce4f
7
- data.tar.gz: beddfa2491ec4ec8d22bac9b4b081933d2751dd9931f849f4713e9a3e2f41aaae8850a88ee3041adb154b1ed960a65949e25e3754d5706b079d1b612182ed77b
6
+ metadata.gz: 7a88219644a5da2c07797b6a9b7e2378c4285498576dcd2b23dd877a8404bbb7be81f08c3aa4acd88d259e9d268748a8026ec5047b4f80ac26b0e240e0c62144
7
+ data.tar.gz: 15a9f2a8851db00e35b065f5143acb85321839f4a1965800b95d01dc44b741737764bcd261c58f637ad17b65707c298c8f6a4b6abe6874539f726a4ce13ebee3
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Checkers
5
+ # The base class for association checkers
6
+ class AssociationChecker < BaseChecker
7
+ attr_reader :model, :association
8
+
9
+ def initialize(model, association)
10
+ @model = model
11
+ @association = association
12
+ end
13
+
14
+ def column_or_attribute_name
15
+ @column_or_attribute_name ||= association.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
@@ -4,16 +4,16 @@ module DatabaseConsistency
4
4
  module Checkers
5
5
  # This class checks if required +belongs_to+ has foreign key constraint
6
6
  class BelongsToPresenceChecker < ValidatorChecker
7
- MISSING_FOREIGN_KEY = 'should have foreign key in the database'
7
+ MISSING_FOREIGN_KEY = 'model should have proper foreign key in the database'
8
8
 
9
9
  private
10
10
 
11
11
  # We skip check when:
12
12
  # - validator is a not a presence validator
13
- # - there is no belongs_to reflection with given name
14
- # - belongs_to reflection is polymorphic
13
+ # - there is no belongs_to association with given name
14
+ # - belongs_to association is polymorphic
15
15
  def preconditions
16
- validator.kind == :presence && reflection && !reflection.polymorphic?
16
+ validator.kind == :presence && association && !association.polymorphic?
17
17
  end
18
18
 
19
19
  # Table of possible statuses
@@ -22,15 +22,15 @@ module DatabaseConsistency
22
22
  # | persisted | ok |
23
23
  # | missing | fail |
24
24
  def check
25
- if model.connection.foreign_keys(model.table_name).find { |fk| fk.column == reflection.foreign_key.to_s }
25
+ if model.connection.foreign_keys(model.table_name).find { |fk| fk.column == association.foreign_key.to_s }
26
26
  report_template(:ok)
27
27
  else
28
28
  report_template(:fail, MISSING_FOREIGN_KEY)
29
29
  end
30
30
  end
31
31
 
32
- def reflection
33
- @reflection ||= model.reflect_on_association(attribute)
32
+ def association
33
+ @association ||= model.reflect_on_association(attribute)
34
34
  end
35
35
  end
36
36
  end
@@ -3,7 +3,7 @@
3
3
  module DatabaseConsistency
4
4
  module Checkers
5
5
  # The base class for table checkers
6
- class TableChecker < BaseChecker
6
+ class ColumnChecker < BaseChecker
7
7
  attr_reader :model, :column
8
8
 
9
9
  def initialize(model, column)
@@ -6,8 +6,8 @@ module DatabaseConsistency
6
6
  class ColumnPresenceChecker < ValidatorChecker
7
7
  WEAK_OPTIONS = %i[allow_nil allow_blank if unless].freeze
8
8
  # Message templates
9
- CONSTRAINT_MISSING = 'should be required in the database'
10
- POSSIBLE_NULL = 'is required but possible null value insert'
9
+ CONSTRAINT_MISSING = 'column should be required in the database'
10
+ POSSIBLE_NULL = 'column is required but there is possible null value insert'
11
11
 
12
12
  private
13
13
 
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Checkers
5
+ # This class checks if association's foreign key has index in the database
6
+ class MissingIndexChecker < AssociationChecker
7
+ # Message templates
8
+ MISSING_INDEX = 'associated model should have proper index in the database'
9
+
10
+ private
11
+
12
+ # We skip check when:
13
+ # - association isn't a `HasOne` or `HasMany`
14
+ def preconditions
15
+ [
16
+ ActiveRecord::Associations::HasOneAssociation,
17
+ ActiveRecord::Associations::HasOneThroughAssociation,
18
+ ActiveRecord::Associations::HasManyAssociation,
19
+ ActiveRecord::Associations::HasManyThroughAssociation
20
+ ].include?(association.association_class)
21
+ end
22
+
23
+ # Table of possible statuses
24
+ # | index | status |
25
+ # | ------------ | ------ |
26
+ # | persisted | ok |
27
+ # | missing | fail |
28
+ def check
29
+ if index
30
+ report_template(:ok)
31
+ else
32
+ report_template(:fail, MISSING_INDEX)
33
+ end
34
+ end
35
+
36
+ def index
37
+ @index ||= association.klass.connection.indexes(association.klass.table_name).find do |index|
38
+ index.columns[0] == association.foreign_key.to_s
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -4,7 +4,7 @@ module DatabaseConsistency
4
4
  module Checkers
5
5
  # This class checks if uniqueness validator has unique index in the database
6
6
  class MissingUniqueIndexChecker < ValidatorChecker
7
- MISSING_INDEX = 'should have unique index in the database'
7
+ MISSING_INDEX = 'model should have proper unique index in the database'
8
8
 
9
9
  def column_or_attribute_name
10
10
  @column_or_attribute_name ||= index_columns.join('+')
@@ -3,9 +3,9 @@
3
3
  module DatabaseConsistency
4
4
  module Checkers
5
5
  # This class checks missing presence validator
6
- class NullConstraintChecker < TableChecker
6
+ class NullConstraintChecker < ColumnChecker
7
7
  # Message templates
8
- VALIDATOR_MISSING = 'is required but do not have presence validator'
8
+ VALIDATOR_MISSING = 'column is required in the database but do not have presence validator'
9
9
 
10
10
  private
11
11
 
@@ -24,7 +24,7 @@ module DatabaseConsistency
24
24
  # | provided | ok |
25
25
  # | missing | fail |
26
26
  #
27
- # We consider PresenceValidation, InclusionValidation or BelongsTo reflection using this column
27
+ # We consider PresenceValidation, InclusionValidation or BelongsTo association using this column
28
28
  def check
29
29
  if valid?
30
30
  report_template(:ok)
@@ -36,7 +36,7 @@ module DatabaseConsistency
36
36
  def valid?
37
37
  validator?(ActiveModel::Validations::PresenceValidator) ||
38
38
  validator?(ActiveModel::Validations::InclusionValidator) ||
39
- belongs_to_reflection?
39
+ belongs_to_association?
40
40
  end
41
41
 
42
42
  def primary_field?
@@ -53,7 +53,7 @@ module DatabaseConsistency
53
53
  end
54
54
  end
55
55
 
56
- def belongs_to_reflection?
56
+ def belongs_to_association?
57
57
  model.reflect_on_all_associations.grep(ActiveRecord::Reflection::BelongsToReflection).any? do |r|
58
58
  Helper.check_inclusion?([r.foreign_key, r.foreign_type], column.name)
59
59
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Processors
5
+ # The class to process associations
6
+ class AssociationsProcessor < BaseProcessor
7
+ CHECKERS = [
8
+ Checkers::MissingIndexChecker
9
+ ].freeze
10
+
11
+ private
12
+
13
+ def check
14
+ Helper.models.flat_map do |model|
15
+ model.reflect_on_all_associations.flat_map do |association|
16
+ CHECKERS.map do |checker_class|
17
+ checker = checker_class.new(model, association)
18
+ checker.report if checker.enabled?(configuration)
19
+ end
20
+ end
21
+ end.compact
22
+ end
23
+ end
24
+ end
25
+ end
@@ -4,7 +4,11 @@ module DatabaseConsistency
4
4
  # The module for processors
5
5
  module Processors
6
6
  def self.reports(configuration)
7
- [ModelsProcessor, TablesProcessor].flat_map do |processor|
7
+ [
8
+ ColumnsProcessor,
9
+ ValidatorsProcessor,
10
+ AssociationsProcessor
11
+ ].flat_map do |processor|
8
12
  processor.new(configuration).reports
9
13
  end
10
14
  end
@@ -2,8 +2,8 @@
2
2
 
3
3
  module DatabaseConsistency
4
4
  module Processors
5
- # The class to process missing validators
6
- class TablesProcessor < BaseProcessor
5
+ # The class to process columns
6
+ class ColumnsProcessor < BaseProcessor
7
7
  CHECKERS = [
8
8
  Checkers::NullConstraintChecker
9
9
  ].freeze
@@ -2,8 +2,8 @@
2
2
 
3
3
  module DatabaseConsistency
4
4
  module Processors
5
- # The class to process all comparators
6
- class ModelsProcessor < BaseProcessor
5
+ # The class to process validators
6
+ class ValidatorsProcessor < BaseProcessor
7
7
  CHECKERS = [
8
8
  Checkers::ColumnPresenceChecker,
9
9
  Checkers::BelongsToPresenceChecker,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DatabaseConsistency
4
- VERSION = '0.5.0'
4
+ VERSION = '0.6.0'
5
5
  end
@@ -10,16 +10,20 @@ require 'database_consistency/writers/base_writer'
10
10
  require 'database_consistency/writers/simple_writer'
11
11
 
12
12
  require 'database_consistency/checkers/base_checker'
13
- require 'database_consistency/checkers/table_checker'
13
+ require 'database_consistency/checkers/association_checker'
14
+ require 'database_consistency/checkers/column_checker'
14
15
  require 'database_consistency/checkers/validator_checker'
16
+
15
17
  require 'database_consistency/checkers/column_presence_checker'
16
18
  require 'database_consistency/checkers/null_constraint_checker'
17
19
  require 'database_consistency/checkers/belongs_to_presence_checker'
18
20
  require 'database_consistency/checkers/missing_unique_index_checker'
21
+ require 'database_consistency/checkers/missing_index_checker'
19
22
 
20
23
  require 'database_consistency/processors/base_processor'
21
- require 'database_consistency/processors/models_processor'
22
- require 'database_consistency/processors/tables_processor'
24
+ require 'database_consistency/processors/associations_processor'
25
+ require 'database_consistency/processors/validators_processor'
26
+ require 'database_consistency/processors/columns_processor'
23
27
 
24
28
  # The root module
25
29
  module DatabaseConsistency
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: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evgeniy Demin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-11 00:00:00.000000000 Z
11
+ date: 2019-01-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -110,18 +110,21 @@ extra_rdoc_files: []
110
110
  files:
111
111
  - bin/database_consistency
112
112
  - lib/database_consistency.rb
113
+ - lib/database_consistency/checkers/association_checker.rb
113
114
  - lib/database_consistency/checkers/base_checker.rb
114
115
  - lib/database_consistency/checkers/belongs_to_presence_checker.rb
116
+ - lib/database_consistency/checkers/column_checker.rb
115
117
  - lib/database_consistency/checkers/column_presence_checker.rb
118
+ - lib/database_consistency/checkers/missing_index_checker.rb
116
119
  - lib/database_consistency/checkers/missing_unique_index_checker.rb
117
120
  - lib/database_consistency/checkers/null_constraint_checker.rb
118
- - lib/database_consistency/checkers/table_checker.rb
119
121
  - lib/database_consistency/checkers/validator_checker.rb
120
122
  - lib/database_consistency/configuration.rb
121
123
  - lib/database_consistency/helper.rb
124
+ - lib/database_consistency/processors/associations_processor.rb
122
125
  - lib/database_consistency/processors/base_processor.rb
123
- - lib/database_consistency/processors/models_processor.rb
124
- - lib/database_consistency/processors/tables_processor.rb
126
+ - lib/database_consistency/processors/columns_processor.rb
127
+ - lib/database_consistency/processors/validators_processor.rb
125
128
  - lib/database_consistency/version.rb
126
129
  - lib/database_consistency/writers/base_writer.rb
127
130
  - lib/database_consistency/writers/simple_writer.rb