database_consistency 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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