database_consistency 0.8.8 → 0.8.13

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: 406fd80b86af26702bba071b8dabe3d8f238923bd7ef6d04776b014d2c5c5575
4
- data.tar.gz: b30e6bee8c79233090fb8a94557217a6e2fc72e618b577b858083bf0cd3ba71e
3
+ metadata.gz: 3d3bf88ec6fae8aac99d835defc6f02c0d16a8bf307c1ff8096c53fa252ef691
4
+ data.tar.gz: dd877669bd9a0de57fcf74969f16ba5d434997b36bcb4e73473e5242546ff6e6
5
5
  SHA512:
6
- metadata.gz: 72147fa9f0eccd7ac75216fe673757541048b143ea31fbab435a83e7cb10f62d3e45ae19a5e0c8e609515d3033fa7d868deba863fd8d7ba152f50d254fb3f534
7
- data.tar.gz: 6c172f7b74de5face1e235103a2821d41be08f282a840b756caf73f24285e8cf6f7e1f5ecf5e40f26160a8036c947c335edc5338ef3ca274a989d9353220f04d
6
+ metadata.gz: c3325319154f7e8420f10d39f1e3a1c325e776f4fda2ddee6e004655ee7526bc535bf8e9c958b79d5e41bb3a44a625b6c31eead26437b12b1649fa9fef3b136d
7
+ data.tar.gz: cee59e3274dc9a841915eb3baf9860cb749a84e1a1baa72e90bde23ba589f2a3d5d8473eda60dc544fa1cbe5fa1ab5496dc64d26ad5052b704ee04b1dbc91c9d
@@ -33,11 +33,15 @@ 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
+
36
39
  require 'database_consistency/processors/base_processor'
37
40
  require 'database_consistency/processors/associations_processor'
38
41
  require 'database_consistency/processors/validators_processor'
39
42
  require 'database_consistency/processors/columns_processor'
40
43
  require 'database_consistency/processors/validators_fractions_processor'
44
+ require 'database_consistency/processors/indexes_processor'
41
45
 
42
46
  # The root module
43
47
  module DatabaseConsistency
@@ -68,7 +68,7 @@ module DatabaseConsistency
68
68
  def associated_key
69
69
  @associated_key ||= (
70
70
  if belongs_to_association?
71
- association.active_record_primary_key
71
+ association.association_primary_key
72
72
  else
73
73
  association.foreign_key
74
74
  end
@@ -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,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 ||= index_columns.join('+')
10
+ @column_or_attribute_name ||= Helper.uniqueness_validator_columns(attribute, validator, model).join('+')
11
11
  end
12
12
 
13
13
  private
@@ -33,41 +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 == sorted_index_columns
36
+ index.unique && Helper.extract_index_columns(index.columns).sort == sorted_uniqueness_validator_columns
37
37
  end
38
38
  end
39
39
 
40
- # @return [Array<String>]
41
- def extract_index_columns(index_columns)
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
- end
49
-
50
- def index_columns
51
- @index_columns ||= ([wrapped_attribute_name] + scope_columns).map(&:to_s)
52
- end
53
-
54
- def scope_columns
55
- @scope_columns ||= Array.wrap(validator.options[:scope]).map do |scope_item|
56
- model._reflect_on_association(scope_item)&.foreign_key || scope_item
57
- end
58
- end
59
-
60
- def sorted_index_columns
61
- @sorted_index_columns ||= index_columns.sort
62
- end
63
-
64
- # @return [String]
65
- def wrapped_attribute_name
66
- if validator.options[:case_sensitive].nil? || validator.options[:case_sensitive]
67
- attribute
68
- else
69
- "lower(#{attribute})"
70
- end
40
+ def sorted_uniqueness_validator_columns
41
+ @sorted_uniqueness_validator_columns ||= Helper.sorted_uniqueness_validator_columns(attribute, validator, model)
71
42
  end
72
43
  end
73
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
@@ -8,7 +8,8 @@ module DatabaseConsistency
8
8
  ColumnsProcessor,
9
9
  ValidatorsProcessor,
10
10
  AssociationsProcessor,
11
- ValidatorsFractionsProcessor
11
+ ValidatorsFractionsProcessor,
12
+ IndexesProcessor
12
13
  ].flat_map do |processor|
13
14
  processor.new(configuration).reports
14
15
  end
@@ -0,0 +1,29 @@
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
+ ].freeze
10
+
11
+ private
12
+
13
+ def check # rubocop:disable Metrics/AbcSize
14
+ Helper.parent_models.flat_map do |model|
15
+ next unless configuration.enabled?(model.name.to_s)
16
+
17
+ indexes = ActiveRecord::Base.connection.indexes(model.table_name)
18
+
19
+ indexes.flat_map do |index|
20
+ enabled_checkers.map do |checker_class|
21
+ checker = checker_class.new(model, index)
22
+ checker.report_if_enabled?(configuration)
23
+ end
24
+ end
25
+ end.compact
26
+ end
27
+ end
28
+ end
29
+ end
@@ -5,3 +5,5 @@ ActiveStorage::Attachment:
5
5
  enabled: false
6
6
  ActiveStorage::Blob:
7
7
  enabled: false
8
+ ActiveStorage::VariantRecord:
9
+ enabled: false
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DatabaseConsistency
4
- VERSION = '0.8.8'
4
+ VERSION = '0.8.13'
5
5
  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: 0.8.8
4
+ version: 0.8.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evgeniy Demin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-24 00:00:00.000000000 Z
11
+ date: 2021-01-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -140,6 +140,8 @@ 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/unique_index_checker.rb
143
145
  - lib/database_consistency/checkers/validator_checkers/belongs_to_presence_checker.rb
144
146
  - lib/database_consistency/checkers/validator_checkers/missing_unique_index_checker.rb
145
147
  - lib/database_consistency/checkers/validator_checkers/validator_checker.rb
@@ -154,6 +156,7 @@ files:
154
156
  - lib/database_consistency/processors/associations_processor.rb
155
157
  - lib/database_consistency/processors/base_processor.rb
156
158
  - lib/database_consistency/processors/columns_processor.rb
159
+ - lib/database_consistency/processors/indexes_processor.rb
157
160
  - lib/database_consistency/processors/validators_fractions_processor.rb
158
161
  - lib/database_consistency/processors/validators_processor.rb
159
162
  - lib/database_consistency/rescue_error.rb