database_consistency 1.5.3 → 1.7.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: f06f5f350f8f4a0dc3eab32d48b01f61da8fde59ebcbc0fcd35296a5a0a2ecd5
4
- data.tar.gz: 13d02eb9836ef51570c33b721909517e1abbbb2d7406e5236a718d040e997f0d
3
+ metadata.gz: 8049cc73c646f8be58c7f7b3491a0dc02f55f3c75eac32803b850f8c272d11fa
4
+ data.tar.gz: fdf3df62bb8df2995889a5c717e22fb437260ebfd77d0bd80bdb5d7b9f90494a
5
5
  SHA512:
6
- metadata.gz: be22b9c36f696268721fdad8fdb8cb5379cb739261d40577754ede248c4cdfd7cf1858f03a6609c762fa500ce87424b3cfc2ed60c93a437bcb2af15dc92f4f8d
7
- data.tar.gz: cdfdaa8f8ba2d0e8af3e510407dcfffb36a1568c380a8be115aa87369bf3f97f45d3c2ebb6587f30a0b2048a576193bf90a168e924f3387f6b05e34f1f4d6ced
6
+ metadata.gz: e05dcd8d5f1dc062e482a7028f2e10c3232377f1fb7c44609ea41fffb9f14fb3a331db407a693fe5ffe1c0f69d0105e3c39b65166210a6ded5365a1e239ebb50
7
+ data.tar.gz: 4dba6ecf15c4f3b6ae3553c28873e23ef77b930a4275124f14b9dfae8b84cb8bfee53033fc4f84a573064c1ebd9b702bb32dddf0fa66c8838e373bb0a372f8ee
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Checkers
5
+ # This class checks missing presence validator
6
+ class EnumValueChecker < ColumnChecker
7
+ Report = ReportBuilder.define(
8
+ DatabaseConsistency::Report,
9
+ :enum_values,
10
+ :declared_values
11
+ )
12
+
13
+ private
14
+
15
+ def report_template(status, declared_values, error_slug: nil)
16
+ Report.new(
17
+ status: status,
18
+ error_slug: error_slug,
19
+ error_message: nil,
20
+ enum_values: enum_column_values,
21
+ declared_values: declared_values,
22
+ **report_attributes
23
+ )
24
+ end
25
+
26
+ def preconditions
27
+ Helper.postgresql? && column.type == :enum && (enum || inclusion_validator)
28
+ end
29
+
30
+ def check
31
+ [
32
+ (verify_enum if enum),
33
+ (verify_inclusion_validator if inclusion_validator)
34
+ ].compact
35
+ end
36
+
37
+ def enum_column_values
38
+ @enum_column_values ||= begin
39
+ _, values = model.connection.enum_types.find { |(enum, _)| enum == column.sql_type }
40
+ values.split(',').map(&:strip)
41
+ end
42
+ end
43
+
44
+ def verify_enum
45
+ values = enum.values.uniq
46
+
47
+ if enum_column_values == values
48
+ report_template(:ok, values)
49
+ else
50
+ report_template(:fail, values, error_slug: :enum_values_inconsistent_with_ar_enum)
51
+ end
52
+ end
53
+
54
+ def verify_inclusion_validator
55
+ values = validator_values(inclusion_validator).uniq
56
+
57
+ if enum_column_values == values
58
+ report_template(:ok, values)
59
+ else
60
+ report_template(:fail, values, error_slug: :enum_values_inconsistent_with_inclusion)
61
+ end
62
+ end
63
+
64
+ def validator_values(validator)
65
+ validator.options[:in] || validator.options[:within]
66
+ end
67
+
68
+ def simple_values_validator?(validator)
69
+ values = validator_values(validator)
70
+
71
+ values.is_a?(Array) && values.all? { |val| val.is_a?(String) }
72
+ end
73
+
74
+ def inclusion_validator
75
+ @inclusion_validator ||= model.validators.find do |validator|
76
+ validator.kind == :inclusion &&
77
+ Helper.check_inclusion?(validator.attributes, column.name) &&
78
+ simple_values_validator?(validator)
79
+ end
80
+ end
81
+
82
+ def enum
83
+ @enum ||= model.defined_enums[column.name]
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Checkers
5
+ # This class checks if uniqueness validator has unique index in the database
6
+ class CaseSensitiveUniqueValidationChecker < ValidatorChecker
7
+ private
8
+
9
+ def preconditions
10
+ validator.kind == :uniqueness && Helper.postgresql? && citext?
11
+ end
12
+
13
+ def check
14
+ if validator.options[:case_sensitive].nil? || validator.options[:case_sensitive]
15
+ report_template(:ok)
16
+ else
17
+ report_template(:fail, error_slug: :redundant_case_insensitive_option)
18
+ end
19
+ end
20
+
21
+ def citext?
22
+ field_name = Helper.foreign_key_or_attribute(model, attribute)
23
+
24
+ field = model.columns.find { |column| column.name.to_s == field_name.to_s }
25
+
26
+ field&.type == :citext
27
+ end
28
+
29
+ def sorted_uniqueness_validator_columns
30
+ @sorted_uniqueness_validator_columns ||= Helper.sorted_uniqueness_validator_columns(attribute, validator, model)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -13,6 +13,10 @@ module DatabaseConsistency
13
13
  end
14
14
  end
15
15
 
16
+ def postgresql?
17
+ adapter == 'postgresql'
18
+ end
19
+
16
20
  def connection_config(klass)
17
21
  if klass.respond_to?(:connection_config)
18
22
  klass.connection_config
@@ -7,7 +7,8 @@ module DatabaseConsistency
7
7
  CHECKERS = [
8
8
  Checkers::NullConstraintChecker,
9
9
  Checkers::LengthConstraintChecker,
10
- Checkers::PrimaryKeyTypeChecker
10
+ Checkers::PrimaryKeyTypeChecker,
11
+ Checkers::EnumValueChecker
11
12
  ].freeze
12
13
 
13
14
  private
@@ -5,7 +5,8 @@ module DatabaseConsistency
5
5
  # The class to process validators
6
6
  class ValidatorsProcessor < BaseProcessor
7
7
  CHECKERS = [
8
- Checkers::MissingUniqueIndexChecker
8
+ Checkers::MissingUniqueIndexChecker,
9
+ Checkers::CaseSensitiveUniqueValidationChecker
9
10
  ].freeze
10
11
 
11
12
  private
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DatabaseConsistency
4
- VERSION = '1.5.3'
4
+ VERSION = '1.7.0'
5
5
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Simple
6
+ class EnumValuesInconsistentWithArEnum < Base # :nodoc:
7
+ private
8
+
9
+ def template
10
+ 'enum has [%<enum_values>s] values but ActiveRecord enum has [%<declared_values>s] values'
11
+ end
12
+
13
+ def attributes
14
+ {
15
+ enum_values: report.enum_values.join(', '),
16
+ declared_values: report.declared_values.join(', ')
17
+ }
18
+ end
19
+
20
+ def unique_attributes
21
+ {
22
+ table_or_model_name: report.table_or_model_name,
23
+ column_or_attribute_name: report.column_or_attribute_name,
24
+ ar_enum: true
25
+ }
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Simple
6
+ class EnumValuesInconsistentWithInclusion < Base # :nodoc:
7
+ private
8
+
9
+ def template
10
+ 'enum has [%<enum_values>s] values but ActiveRecord inclusion validation has [%<declared_values>s] values'
11
+ end
12
+
13
+ def attributes
14
+ {
15
+ enum_values: report.enum_values.join(', '),
16
+ declared_values: report.declared_values.join(', ')
17
+ }
18
+ end
19
+
20
+ def unique_attributes
21
+ {
22
+ table_or_model_name: report.table_or_model_name,
23
+ column_or_attribute_name: report.column_or_attribute_name,
24
+ inclusion: true
25
+ }
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Simple
6
+ class RedundantCaseInsensitiveOption < Base # :nodoc:
7
+ private
8
+
9
+ def template
10
+ "has case insensitive type and doesn't require case_sensitive: false option"
11
+ end
12
+
13
+ def unique_attributes
14
+ {
15
+ table_or_model_name: report.table_or_model_name,
16
+ column_or_attribute_name: report.column_or_attribute_name
17
+ }
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -25,7 +25,10 @@ module DatabaseConsistency
25
25
  redundant_unique_index: Simple::RedundantUniqueIndex,
26
26
  small_primary_key: Simple::SmallPrimaryKey,
27
27
  inconsistent_enum_type: Simple::InconsistentEnumType,
28
- missing_foreign_key_cascade: Simple::MissingForeignKeyCascade
28
+ missing_foreign_key_cascade: Simple::MissingForeignKeyCascade,
29
+ enum_values_inconsistent_with_ar_enum: Simple::EnumValuesInconsistentWithArEnum,
30
+ enum_values_inconsistent_with_inclusion: Simple::EnumValuesInconsistentWithInclusion,
31
+ redundant_case_insensitive_option: Simple::RedundantCaseInsensitiveOption
29
32
  }.freeze
30
33
 
31
34
  def write
@@ -35,6 +35,9 @@ require 'database_consistency/writers/simple/null_constraint_missing'
35
35
  require 'database_consistency/writers/simple/possible_null'
36
36
  require 'database_consistency/writers/simple/small_primary_key'
37
37
  require 'database_consistency/writers/simple/inconsistent_enum_type'
38
+ require 'database_consistency/writers/simple/enum_values_inconsistent_with_ar_enum'
39
+ require 'database_consistency/writers/simple/enum_values_inconsistent_with_inclusion'
40
+ require 'database_consistency/writers/simple/redundant_case_insensitive_option'
38
41
  require 'database_consistency/writers/simple_writer'
39
42
 
40
43
  require 'database_consistency/writers/autofix/helpers/migration'
@@ -67,9 +70,11 @@ require 'database_consistency/checkers/column_checkers/column_checker'
67
70
  require 'database_consistency/checkers/column_checkers/null_constraint_checker'
68
71
  require 'database_consistency/checkers/column_checkers/length_constraint_checker'
69
72
  require 'database_consistency/checkers/column_checkers/primary_key_type_checker'
73
+ require 'database_consistency/checkers/column_checkers/enum_value_checker'
70
74
 
71
75
  require 'database_consistency/checkers/validator_checkers/validator_checker'
72
76
  require 'database_consistency/checkers/validator_checkers/missing_unique_index_checker'
77
+ require 'database_consistency/checkers/validator_checkers/case_sensitive_unique_validation_checker'
73
78
 
74
79
  require 'database_consistency/checkers/validators_fraction_checkers/validators_fraction_checker'
75
80
  require 'database_consistency/checkers/validators_fraction_checkers/column_presence_checker'
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: 1.5.3
4
+ version: 1.7.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: 2022-12-01 00:00:00.000000000 Z
11
+ date: 2022-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -153,6 +153,7 @@ files:
153
153
  - lib/database_consistency/checkers/association_checkers/missing_index_checker.rb
154
154
  - lib/database_consistency/checkers/base_checker.rb
155
155
  - lib/database_consistency/checkers/column_checkers/column_checker.rb
156
+ - lib/database_consistency/checkers/column_checkers/enum_value_checker.rb
156
157
  - lib/database_consistency/checkers/column_checkers/length_constraint_checker.rb
157
158
  - lib/database_consistency/checkers/column_checkers/null_constraint_checker.rb
158
159
  - lib/database_consistency/checkers/column_checkers/primary_key_type_checker.rb
@@ -162,6 +163,7 @@ files:
162
163
  - lib/database_consistency/checkers/index_checkers/redundant_index_checker.rb
163
164
  - lib/database_consistency/checkers/index_checkers/redundant_unique_index_checker.rb
164
165
  - lib/database_consistency/checkers/index_checkers/unique_index_checker.rb
166
+ - lib/database_consistency/checkers/validator_checkers/case_sensitive_unique_validation_checker.rb
165
167
  - lib/database_consistency/checkers/validator_checkers/missing_unique_index_checker.rb
166
168
  - lib/database_consistency/checkers/validator_checkers/validator_checker.rb
167
169
  - lib/database_consistency/checkers/validators_fraction_checkers/column_presence_checker.rb
@@ -206,6 +208,8 @@ files:
206
208
  - lib/database_consistency/writers/simple/association_missing_null_constraint.rb
207
209
  - lib/database_consistency/writers/simple/base.rb
208
210
  - lib/database_consistency/writers/simple/default_message.rb
211
+ - lib/database_consistency/writers/simple/enum_values_inconsistent_with_ar_enum.rb
212
+ - lib/database_consistency/writers/simple/enum_values_inconsistent_with_inclusion.rb
209
213
  - lib/database_consistency/writers/simple/has_one_missing_unique_index.rb
210
214
  - lib/database_consistency/writers/simple/inconsistent_enum_type.rb
211
215
  - lib/database_consistency/writers/simple/inconsistent_types.rb
@@ -220,6 +224,7 @@ files:
220
224
  - lib/database_consistency/writers/simple/null_constraint_misses_validator.rb
221
225
  - lib/database_consistency/writers/simple/null_constraint_missing.rb
222
226
  - lib/database_consistency/writers/simple/possible_null.rb
227
+ - lib/database_consistency/writers/simple/redundant_case_insensitive_option.rb
223
228
  - lib/database_consistency/writers/simple/redundant_index.rb
224
229
  - lib/database_consistency/writers/simple/redundant_unique_index.rb
225
230
  - lib/database_consistency/writers/simple/small_primary_key.rb