database_consistency 1.3.4 → 1.3.6

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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/lib/database_consistency/checkers/association_checkers/foreign_key_type_checker.rb +28 -12
  3. data/lib/database_consistency/checkers/association_checkers/missing_index_checker.rb +21 -0
  4. data/lib/database_consistency/checkers/column_checkers/primary_key_type_checker.rb +29 -2
  5. data/lib/database_consistency/checkers/validator_checkers/missing_unique_index_checker.rb +19 -2
  6. data/lib/database_consistency/databases/types/base.rb +6 -0
  7. data/lib/database_consistency/version.rb +1 -1
  8. data/lib/database_consistency/writers/autofix/association_missing_index.rb +39 -0
  9. data/lib/database_consistency/writers/autofix/has_one_missing_unique_index.rb +19 -0
  10. data/lib/database_consistency/writers/autofix/inconsistent_types.rb +27 -0
  11. data/lib/database_consistency/writers/autofix/templates/association_missing_index.tt +5 -0
  12. data/lib/database_consistency/writers/autofix/templates/has_one_missing_unique_index.tt +5 -0
  13. data/lib/database_consistency/writers/autofix/templates/inconsistent_types.tt +5 -0
  14. data/lib/database_consistency/writers/autofix/templates/null_constraint_missing.tt +1 -1
  15. data/lib/database_consistency/writers/autofix_writer.rb +9 -4
  16. data/lib/database_consistency/writers/simple/association_missing_index.rb +22 -0
  17. data/lib/database_consistency/writers/simple/association_missing_null_constraint.rb +22 -0
  18. data/lib/database_consistency/writers/simple/base.rb +8 -0
  19. data/lib/database_consistency/writers/simple/error_message.rb +7 -0
  20. data/lib/database_consistency/writers/simple/has_one_missing_unique_index.rb +23 -0
  21. data/lib/database_consistency/writers/simple/inconsistent_types.rb +8 -0
  22. data/lib/database_consistency/writers/simple/length_validator_greater_limit.rb +22 -0
  23. data/lib/database_consistency/writers/simple/length_validator_lower_limit.rb +22 -0
  24. data/lib/database_consistency/writers/simple/length_validator_missing.rb +22 -0
  25. data/lib/database_consistency/writers/simple/missing_foreign_key.rb +24 -0
  26. data/lib/database_consistency/writers/simple/missing_unique_index.rb +23 -0
  27. data/lib/database_consistency/writers/simple/missing_uniqueness_validation.rb +22 -0
  28. data/lib/database_consistency/writers/simple/null_constraint_association_misses_validator.rb +7 -0
  29. data/lib/database_consistency/writers/simple/null_constraint_misses_validator.rb +22 -0
  30. data/lib/database_consistency/writers/simple/null_constraint_missing.rb +22 -0
  31. data/lib/database_consistency/writers/simple/possible_null.rb +22 -0
  32. data/lib/database_consistency/writers/simple/redundant_index.rb +6 -0
  33. data/lib/database_consistency/writers/simple/redundant_unique_index.rb +6 -0
  34. data/lib/database_consistency/writers/simple/small_primary_key.rb +22 -0
  35. data/lib/database_consistency/writers/simple_writer.rb +20 -21
  36. data/lib/database_consistency.rb +16 -0
  37. metadata +21 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1f1aad5cf1e4812b31d9bc7df0402f64dd32bb7ebdb9ab4ec7bf41bb195622dc
4
- data.tar.gz: 1fc95e58bd89e9faf0004d7faf5cc2635d5432785d2e1a57d9965e413abf4c41
3
+ metadata.gz: ad00c3759184fa0098812d4cb79169f109205bff2861c37965d56c42c4da568f
4
+ data.tar.gz: 579087c2a52d57bac85af5fc7f9e86fa31b6c78bbaab1583128e319f9156dafb
5
5
  SHA512:
6
- metadata.gz: 6d5d98750608c54e20a5f6990b54c37df89717d7009d46b099b62695b90c2a29ab44f35dab299c1e3e0f83ff4d77f5709e6a42aa7130190fcbb1807b5a6628b9
7
- data.tar.gz: ff7a4d0fa92518ed33393c8e1614852ef9ec168ee5a4ac857a653881a268511ad877b982633553e7341ce8a740dbf7ae402002e991210784614e397dbe07ed36
6
+ metadata.gz: 206324a83d7f850bde79bb8a4399362ba7ff4f94cf848139d55781cf7e6f54d8b03d5e4641928193689c0c818c803badbcbb4f72685031f72dab26eea1f4a80a
7
+ data.tar.gz: 2cbaed407b168b1100de5cb6962d2fedac6ce2e8f955a5ed4811ef9d80227a2f3f396de98c9ed0a9de8c5ca751c092f389b482852663a510860cbaad85866643
@@ -4,17 +4,21 @@ module DatabaseConsistency
4
4
  module Checkers
5
5
  # This class checks if association's foreign key type covers associated model's primary key (same or bigger)
6
6
  class ForeignKeyTypeChecker < AssociationChecker
7
- class Report < DatabaseConsistency::Report # :nodoc:
8
- attr_reader :pk_name, :pk_type, :fk_name, :fk_type
9
-
10
- def initialize(fk_name: nil, fk_type: nil, pk_name: nil, pk_type: nil, **args)
11
- super(**args)
12
- @fk_name = fk_name
13
- @fk_type = fk_type
14
- @pk_name = pk_name
15
- @pk_type = pk_type
7
+ ALLOWED_TYPES =
8
+
9
+ class Report < DatabaseConsistency::Report # :nodoc:
10
+ attr_reader :pk_name, :pk_type, :fk_name, :fk_type, :table_to_change, :type_to_set
11
+
12
+ def initialize(fk_name: nil, fk_type: nil, pk_name: nil, pk_type: nil, table_to_change: nil, type_to_set: nil, **args) # rubocop:disable Metrics/ParameterLists, Layout/LineLength
13
+ super(**args)
14
+ @table_to_change = table_to_change
15
+ @type_to_set = type_to_set
16
+ @fk_name = fk_name
17
+ @fk_type = fk_type
18
+ @pk_name = pk_name
19
+ @pk_type = pk_type
20
+ end
16
21
  end
17
- end
18
22
 
19
23
  private
20
24
 
@@ -37,9 +41,11 @@ module DatabaseConsistency
37
41
  # | ------------- | ------ |
38
42
  # | covers | ok |
39
43
  # | doesn't cover | fail |
40
- def check # rubocop:disable Metrics/MethodLength
44
+ def check # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
41
45
  if converted_type(associated_column).cover?(converted_type(primary_column))
42
46
  report_template(:ok)
47
+ elsif !(converted_type(associated_column).numeric? && converted_type(primary_column).numeric?)
48
+ report_template(:ok)
43
49
  else
44
50
  report_template(:fail, error_slug: :inconsistent_types)
45
51
  end
@@ -52,11 +58,13 @@ module DatabaseConsistency
52
58
  )
53
59
  end
54
60
 
55
- def report_template(status, error_slug: nil)
61
+ def report_template(status, error_slug: nil) # rubocop:disable Metrics/MethodLength
56
62
  Report.new(
57
63
  status: status,
58
64
  error_slug: error_slug,
59
65
  error_message: nil,
66
+ table_to_change: table_to_change,
67
+ type_to_set: converted_type(primary_column).convert,
60
68
  fk_type: converted_type(associated_column).type,
61
69
  fk_name: associated_key,
62
70
  pk_type: converted_type(primary_column).type,
@@ -65,6 +73,14 @@ module DatabaseConsistency
65
73
  )
66
74
  end
67
75
 
76
+ def table_to_change
77
+ @table_to_change ||= if belongs_to_association?
78
+ association.active_record.table_name
79
+ else
80
+ association.klass.table_name
81
+ end
82
+ end
83
+
68
84
  # @return [String]
69
85
  def primary_key
70
86
  @primary_key ||= if belongs_to_association?
@@ -4,6 +4,16 @@ module DatabaseConsistency
4
4
  module Checkers
5
5
  # This class checks if association's foreign key has index in the database
6
6
  class MissingIndexChecker < AssociationChecker
7
+ class Report < DatabaseConsistency::Report # :nodoc:
8
+ attr_reader :table_name, :columns
9
+
10
+ def initialize(table_name:, columns:, **args)
11
+ super(**args)
12
+ @table_name = table_name
13
+ @columns = columns
14
+ end
15
+ end
16
+
7
17
  private
8
18
 
9
19
  # We skip check when:
@@ -48,6 +58,17 @@ module DatabaseConsistency
48
58
  end
49
59
  end
50
60
 
61
+ def report_template(status, error_slug: nil)
62
+ Report.new(
63
+ status: status,
64
+ error_slug: error_slug,
65
+ error_message: nil,
66
+ table_name: association.klass.table_name,
67
+ columns: association_keys,
68
+ **report_attributes
69
+ )
70
+ end
71
+
51
72
  def unique_has_one_association?
52
73
  association.scope.nil? && association.macro == :has_one && !association.options[:as].present?
53
74
  end
@@ -4,9 +4,24 @@ module DatabaseConsistency
4
4
  module Checkers
5
5
  # This class checks missing presence validator
6
6
  class PrimaryKeyTypeChecker < ColumnChecker
7
+ class Report < DatabaseConsistency::Report # :nodoc:
8
+ attr_reader :fk_name, :table_to_change, :type_to_set
9
+
10
+ def initialize(fk_name: nil, table_to_change: nil, type_to_set: nil, **args)
11
+ super(**args)
12
+ @table_to_change = table_to_change
13
+ @type_to_set = type_to_set
14
+ @fk_name = fk_name
15
+ end
16
+ end
17
+
7
18
  private
8
19
 
9
20
  VALID_TYPES = %w[bigserial bigint uuid].freeze
21
+ VALID_TYPES_MAP = {
22
+ 'serial' => 'bigserial',
23
+ 'integer' => 'bigint'
24
+ }.freeze
10
25
  SQLITE_ADAPTER_NAME = 'SQLite'
11
26
 
12
27
  # We skip check when:
@@ -21,14 +36,26 @@ module DatabaseConsistency
21
36
  # | --------------------- | ------ |
22
37
  # | yes | ok |
23
38
  # | no | fail |
24
- def check
39
+ def check # rubocop:disable Metrics/MethodLength
25
40
  if valid?
26
41
  report_template(:ok)
27
42
  else
28
- report_template(:fail, error_slug: :small_primary_key)
43
+ Report.new(
44
+ status: :fail,
45
+ error_slug: :small_primary_key,
46
+ error_message: nil,
47
+ table_to_change: model.table_name,
48
+ fk_name: column.name,
49
+ type_to_set: type_to_set,
50
+ **report_attributes
51
+ )
29
52
  end
30
53
  end
31
54
 
55
+ def type_to_set
56
+ VALID_TYPES_MAP[column.sql_type.to_s] || 'bigserial'
57
+ end
58
+
32
59
  # @return [Boolean]
33
60
  def valid?
34
61
  VALID_TYPES.any? do |type|
@@ -4,6 +4,16 @@ 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
+ class Report < DatabaseConsistency::Report # :nodoc:
8
+ attr_reader :table_name, :columns
9
+
10
+ def initialize(table_name:, columns:, **args)
11
+ super(**args)
12
+ @table_name = table_name
13
+ @columns = columns
14
+ end
15
+ end
16
+
7
17
  def column_or_attribute_name
8
18
  @column_or_attribute_name ||= Helper.uniqueness_validator_columns(attribute, validator, model).join('+')
9
19
  end
@@ -21,11 +31,18 @@ module DatabaseConsistency
21
31
  # | ------------ | ------ |
22
32
  # | persisted | ok |
23
33
  # | missing | fail |
24
- def check
34
+ def check # rubocop:disable Metrics/MethodLength
25
35
  if unique_index
26
36
  report_template(:ok)
27
37
  else
28
- report_template(:fail, error_slug: :missing_unique_index)
38
+ Report.new(
39
+ status: :fail,
40
+ error_slug: :missing_unique_index,
41
+ error_message: nil,
42
+ table_name: model.table_name,
43
+ columns: sorted_uniqueness_validator_columns,
44
+ **report_attributes
45
+ )
29
46
  end
30
47
  end
31
48
 
@@ -7,6 +7,8 @@ module DatabaseConsistency
7
7
  class Base
8
8
  attr_reader :type
9
9
 
10
+ NUMERIC_TYPES = %w[bigserial serial bigint integer smallint].freeze
11
+
10
12
  COVERED_TYPES = {
11
13
  'bigint' => %w[integer bigint],
12
14
  'integer' => %w[integer smallint]
@@ -22,6 +24,10 @@ module DatabaseConsistency
22
24
  type
23
25
  end
24
26
 
27
+ def numeric?
28
+ NUMERIC_TYPES.include?(convert)
29
+ end
30
+
25
31
  # @param [DatabaseConsistency::Databases::Types::Base]
26
32
  #
27
33
  # @return [Boolean]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DatabaseConsistency
4
- VERSION = '1.3.4'
4
+ VERSION = '1.3.6'
5
5
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Autofix
6
+ class AssociationMissingIndex < MigrationBase # :nodoc:
7
+ def attributes
8
+ {
9
+ table_name: report.table_name,
10
+ columns: columns,
11
+ index_name: index_name
12
+ }
13
+ end
14
+
15
+ private
16
+
17
+ def migration_name
18
+ "add_#{report.table_name}_#{columns_key}_index"
19
+ end
20
+
21
+ def template_path
22
+ File.join(__dir__, 'templates', 'association_missing_index.tt')
23
+ end
24
+
25
+ def columns
26
+ "%w[#{report.columns.join(' ')}]"
27
+ end
28
+
29
+ def columns_key
30
+ report.columns.join('_').gsub('(', '_').gsub(')', '_')
31
+ end
32
+
33
+ def index_name
34
+ "index_#{report.table_name}_#{columns_key}".first(63)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Autofix
6
+ class HasOneMissingUniqueIndex < AssociationMissingIndex # :nodoc:
7
+ def attributes
8
+ super.merge(unique: true)
9
+ end
10
+
11
+ private
12
+
13
+ def template_path
14
+ File.join(__dir__, 'templates', 'has_one_missing_unique_index.tt')
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Autofix
6
+ class InconsistentTypes < MigrationBase # :nodoc:
7
+ def attributes
8
+ {
9
+ table_to_change: report.table_to_change,
10
+ type_to_set: report.type_to_set,
11
+ fk_name: report.fk_name
12
+ }
13
+ end
14
+
15
+ private
16
+
17
+ def migration_name
18
+ "change_#{report.table_to_change}_#{report.fk_name}_to_#{report.type_to_set}"
19
+ end
20
+
21
+ def template_path
22
+ File.join(__dir__, 'templates', 'inconsistent_types.tt')
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,5 @@
1
+ class %<migration_name>s < ActiveRecord::Migration[%<migration_version>s]
2
+ def change
3
+ add_index :%<table_name>s, %<columns>s, name: :%<index_name>s
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class %<migration_name>s < ActiveRecord::Migration[%<migration_version>s]
2
+ def change
3
+ add_index :%<table_name>s, %<columns>s, name: :%<index_name>s, unique: true
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class %<migration_name>s < ActiveRecord::Migration[%<migration_version>s]
2
+ def change
3
+ change_column :%<table_to_change>s, :%<fk_name>s, :%<type_to_set>s
4
+ end
5
+ end
@@ -1,5 +1,5 @@
1
1
  class %<migration_name>s < ActiveRecord::Migration[%<migration_version>s]
2
2
  def change
3
- change_column_null(:%<table_name>s, :%<column_name>s, false)
3
+ change_column_null :%<table_name>s, :%<column_name>s, false
4
4
  end
5
5
  end
@@ -6,11 +6,16 @@ module DatabaseConsistency
6
6
  # The simplest formatter
7
7
  class AutofixWriter < BaseWriter
8
8
  SLUG_TO_GENERATOR = {
9
+ association_missing_index: Autofix::AssociationMissingIndex,
10
+ association_missing_null_constraint: Autofix::NullConstraintMissing,
11
+ has_one_missing_unique_index: Autofix::HasOneMissingUniqueIndex,
12
+ inconsistent_types: Autofix::InconsistentTypes,
9
13
  missing_foreign_key: Autofix::MissingForeignKey,
14
+ missing_unique_index: Autofix::HasOneMissingUniqueIndex,
10
15
  null_constraint_missing: Autofix::NullConstraintMissing,
11
- association_missing_null_constraint: Autofix::NullConstraintMissing,
12
16
  redundant_index: Autofix::RedundantIndex,
13
- redundant_unique_index: Autofix::RedundantIndex
17
+ redundant_unique_index: Autofix::RedundantIndex,
18
+ small_primary_key: Autofix::InconsistentTypes
14
19
  }.freeze
15
20
 
16
21
  def write
@@ -36,8 +41,8 @@ module DatabaseConsistency
36
41
  klass&.new(report)
37
42
  end
38
43
 
39
- def unique_key(report)
40
- [report.class, report.attributes]
44
+ def unique_key(generator)
45
+ [generator.class, generator.attributes]
41
46
  end
42
47
  end
43
48
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Simple
6
+ class AssociationMissingIndex < Base # :nodoc:
7
+ private
8
+
9
+ def template
10
+ 'associated model should have proper index in the database'
11
+ end
12
+
13
+ def unique_attributes
14
+ {
15
+ table_name: report.table_name,
16
+ columns: report.columns
17
+ }
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Simple
6
+ class AssociationMissingNullConstraint < Base # :nodoc:
7
+ private
8
+
9
+ def template
10
+ 'association foreign key column should be required in the database'
11
+ end
12
+
13
+ def unique_attributes
14
+ {
15
+ table_name: report.table_name,
16
+ column_name: report.column_name
17
+ }
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -36,8 +36,16 @@ module DatabaseConsistency
36
36
  "#{report.checker_name} #{status_text} #{key_text} #{message_text}"
37
37
  end
38
38
 
39
+ def unique_key
40
+ { class: self.class }.merge(unique_attributes)
41
+ end
42
+
39
43
  private
40
44
 
45
+ def unique_attributes
46
+ raise StandardError, 'Missing the implementation'
47
+ end
48
+
41
49
  def message_text
42
50
  template % attributes
43
51
  end
@@ -9,6 +9,13 @@ module DatabaseConsistency
9
9
  def template
10
10
  report.error_message || ''
11
11
  end
12
+
13
+ def unique_attributes
14
+ {
15
+ template: template,
16
+ checker_name: report.checker_name
17
+ }
18
+ end
12
19
  end
13
20
  end
14
21
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Simple
6
+ class HasOneMissingUniqueIndex < Base # :nodoc:
7
+ private
8
+
9
+ def template
10
+ 'associated model should have proper unique index in the database'
11
+ end
12
+
13
+ def unique_attributes
14
+ {
15
+ table_name: report.table_name,
16
+ columns: report.columns,
17
+ unique: true
18
+ }
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -18,6 +18,14 @@ module DatabaseConsistency
18
18
  pk_type: report.pk_type
19
19
  }
20
20
  end
21
+
22
+ def unique_attributes
23
+ {
24
+ table_to_change: report.table_to_change,
25
+ type_to_set: report.type_to_set,
26
+ fk_name: report.fk_name
27
+ }
28
+ end
21
29
  end
22
30
  end
23
31
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Simple
6
+ class LengthValidatorGreaterLimit < Base # :nodoc:
7
+ private
8
+
9
+ def template
10
+ 'column has greater limit in the database than in length validator'
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
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Simple
6
+ class LengthValidatorLowerLimit < Base # :nodoc:
7
+ private
8
+
9
+ def template
10
+ 'column has lower limit in the database than in length validator'
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
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Simple
6
+ class LengthValidatorMissing < Base # :nodoc:
7
+ private
8
+
9
+ def template
10
+ 'column has limit in the database but do not have length validator'
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
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Simple
6
+ class MissingForeignKey < Base # :nodoc:
7
+ private
8
+
9
+ def template
10
+ 'should have foreign key in the database'
11
+ end
12
+
13
+ def unique_attributes
14
+ {
15
+ foreign_table: report.foreign_table,
16
+ foreign_key: report.foreign_key,
17
+ primary_table: report.primary_table,
18
+ primary_key: report.primary_key
19
+ }
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Simple
6
+ class MissingUniqueIndex < Base # :nodoc:
7
+ private
8
+
9
+ def template
10
+ 'model should have proper unique index in the database'
11
+ end
12
+
13
+ def unique_attributes
14
+ {
15
+ table_name: report.table_name,
16
+ columns: report.columns,
17
+ unique: true
18
+ }
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Simple
6
+ class MissingUniquenessValidation < Base # :nodoc:
7
+ private
8
+
9
+ def template
10
+ 'index is unique in the database but do not have uniqueness validator'
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
@@ -15,6 +15,13 @@ module DatabaseConsistency
15
15
  association_name: report.association_name
16
16
  }
17
17
  end
18
+
19
+ def unique_attributes
20
+ {
21
+ table_or_model_name: report.table_or_model_name,
22
+ column_or_attribute_name: report.column_or_attribute_name
23
+ }
24
+ end
18
25
  end
19
26
  end
20
27
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Simple
6
+ class NullConstraintMissesValidator < Base # :nodoc:
7
+ private
8
+
9
+ def template
10
+ 'column is required in the database but do not have presence validator'
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
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Simple
6
+ class NullConstraintMissing < Base # :nodoc:
7
+ private
8
+
9
+ def template
10
+ 'column should be required in the database'
11
+ end
12
+
13
+ def unique_attributes
14
+ {
15
+ table_name: report.table_name,
16
+ column_name: report.column_name
17
+ }
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Simple
6
+ class PossibleNull < Base # :nodoc:
7
+ private
8
+
9
+ def template
10
+ 'column is required but there is possible null value insert'
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
@@ -15,6 +15,12 @@ module DatabaseConsistency
15
15
  covered_index_name: report.covered_index_name
16
16
  }
17
17
  end
18
+
19
+ def unique_attributes
20
+ {
21
+ index_name: report.index_name
22
+ }
23
+ end
18
24
  end
19
25
  end
20
26
  end
@@ -15,6 +15,12 @@ module DatabaseConsistency
15
15
  covered_index_name: report.covered_index_name
16
16
  }
17
17
  end
18
+
19
+ def unique_attributes
20
+ {
21
+ index_name: report.index_name
22
+ }
23
+ end
18
24
  end
19
25
  end
20
26
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Simple
6
+ class SmallPrimaryKey < Base # :nodoc:
7
+ private
8
+
9
+ def template
10
+ 'column has int/serial type but recommended to have bigint/bigserial/uuid'
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
@@ -6,39 +6,38 @@ module DatabaseConsistency
6
6
  # The simplest formatter
7
7
  class SimpleWriter < BaseWriter
8
8
  SLUG_TO_WRITER = {
9
- missing_foreign_key: Simple::Base.with('should have foreign key in the database'),
9
+ association_missing_index: Simple::AssociationMissingIndex,
10
+ association_missing_null_constraint: Simple::AssociationMissingNullConstraint,
11
+ has_one_missing_unique_index: Simple::HasOneMissingUniqueIndex,
10
12
  inconsistent_types: Simple::InconsistentTypes,
11
- has_one_missing_unique_index: Simple::Base.with('associated model should have proper unique index in the database'), # rubocop:disable Layout/LineLength
12
- association_missing_index: Simple::Base.with('associated model should have proper index in the database'),
13
- length_validator_missing: Simple::Base.with('column has limit in the database but do not have length validator'), # rubocop:disable Layout/LineLength
14
- length_validator_greater_limit: Simple::Base.with('column has greater limit in the database than in length validator'), # rubocop:disable Layout/LineLength
15
- length_validator_lower_limit: Simple::Base.with('column has lower limit in the database than in length validator'), # rubocop:disable Layout/LineLength
16
- null_constraint_misses_validator: Simple::Base.with('column is required in the database but do not have presence validator'), # rubocop:disable Layout/LineLength
17
- small_primary_key: Simple::Base.with('column has int/serial type but recommended to have bigint/bigserial/uuid'), # rubocop:disable Layout/LineLength
18
- missing_uniqueness_validation: Simple::Base.with('index is unique in the database but do not have uniqueness validator'), # rubocop:disable Layout/LineLength
19
- missing_unique_index: Simple::Base.with('model should have proper unique index in the database'),
20
- possible_null: Simple::Base.with('column is required but there is possible null value insert'),
21
- null_constraint_missing: Simple::Base.with('column should be required in the database'),
22
- association_missing_null_constraint: Simple::Base.with('association foreign key column should be required in the database'), # rubocop:disable Layout/LineLength
13
+ length_validator_greater_limit: Simple::LengthValidatorGreaterLimit,
14
+ length_validator_lower_limit: Simple::LengthValidatorLowerLimit,
15
+ length_validator_missing: Simple::LengthValidatorMissing,
16
+ missing_foreign_key: Simple::MissingForeignKey,
17
+ missing_unique_index: Simple::MissingUniqueIndex,
18
+ missing_uniqueness_validation: Simple::MissingUniquenessValidation,
23
19
  null_constraint_association_misses_validator: Simple::NullConstraintAssociationMissesValidator,
20
+ null_constraint_misses_validator: Simple::NullConstraintMissesValidator,
21
+ null_constraint_missing: Simple::NullConstraintMissing,
22
+ possible_null: Simple::PossibleNull,
24
23
  redundant_index: Simple::RedundantIndex,
25
- redundant_unique_index: Simple::RedundantUniqueIndex
24
+ redundant_unique_index: Simple::RedundantUniqueIndex,
25
+ small_primary_key: Simple::SmallPrimaryKey
26
26
  }.freeze
27
27
 
28
28
  def write
29
- results.each do |result|
30
- next unless write?(result.status)
31
-
32
- writer = writer(result)
33
-
29
+ results.select(&method(:write?))
30
+ .map(&method(:writer))
31
+ .uniq(&:unique_key)
32
+ .each do |writer|
34
33
  puts writer.msg
35
34
  end
36
35
  end
37
36
 
38
37
  private
39
38
 
40
- def write?(status)
41
- status == :fail || config.debug?
39
+ def write?(report)
40
+ report.status == :fail || config.debug?
42
41
  end
43
42
 
44
43
  def writer(report)
@@ -18,12 +18,28 @@ require 'database_consistency/writers/simple/inconsistent_types'
18
18
  require 'database_consistency/writers/simple/null_constraint_association_misses_validator'
19
19
  require 'database_consistency/writers/simple/redundant_index'
20
20
  require 'database_consistency/writers/simple/redundant_unique_index'
21
+ require 'database_consistency/writers/simple/association_missing_index'
22
+ require 'database_consistency/writers/simple/association_missing_null_constraint'
23
+ require 'database_consistency/writers/simple/has_one_missing_unique_index'
24
+ require 'database_consistency/writers/simple/length_validator_lower_limit'
25
+ require 'database_consistency/writers/simple/length_validator_greater_limit'
26
+ require 'database_consistency/writers/simple/length_validator_missing'
27
+ require 'database_consistency/writers/simple/missing_foreign_key'
28
+ require 'database_consistency/writers/simple/missing_unique_index'
29
+ require 'database_consistency/writers/simple/missing_uniqueness_validation'
30
+ require 'database_consistency/writers/simple/null_constraint_misses_validator'
31
+ require 'database_consistency/writers/simple/null_constraint_missing'
32
+ require 'database_consistency/writers/simple/possible_null'
33
+ require 'database_consistency/writers/simple/small_primary_key'
21
34
  require 'database_consistency/writers/simple_writer'
22
35
 
23
36
  require 'database_consistency/writers/autofix/helpers/migration'
24
37
  require 'database_consistency/writers/autofix/base'
25
38
  require 'database_consistency/writers/autofix/migration_base'
26
39
  require 'database_consistency/writers/autofix/missing_foreign_key'
40
+ require 'database_consistency/writers/autofix/inconsistent_types'
41
+ require 'database_consistency/writers/autofix/association_missing_index'
42
+ require 'database_consistency/writers/autofix/has_one_missing_unique_index'
27
43
  require 'database_consistency/writers/autofix/redundant_index'
28
44
  require 'database_consistency/writers/autofix/null_constraint_missing'
29
45
  require 'database_consistency/writers/autofix_writer'
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.3.4
4
+ version: 1.3.6
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-11-12 00:00:00.000000000 Z
11
+ date: 2022-11-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -179,23 +179,42 @@ files:
179
179
  - lib/database_consistency/rescue_error.rb
180
180
  - lib/database_consistency/templates/rails_defaults.yml
181
181
  - lib/database_consistency/version.rb
182
+ - lib/database_consistency/writers/autofix/association_missing_index.rb
182
183
  - lib/database_consistency/writers/autofix/base.rb
184
+ - lib/database_consistency/writers/autofix/has_one_missing_unique_index.rb
183
185
  - lib/database_consistency/writers/autofix/helpers/migration.rb
186
+ - lib/database_consistency/writers/autofix/inconsistent_types.rb
184
187
  - lib/database_consistency/writers/autofix/migration_base.rb
185
188
  - lib/database_consistency/writers/autofix/missing_foreign_key.rb
186
189
  - lib/database_consistency/writers/autofix/null_constraint_missing.rb
187
190
  - lib/database_consistency/writers/autofix/redundant_index.rb
191
+ - lib/database_consistency/writers/autofix/templates/association_missing_index.tt
192
+ - lib/database_consistency/writers/autofix/templates/has_one_missing_unique_index.tt
193
+ - lib/database_consistency/writers/autofix/templates/inconsistent_types.tt
188
194
  - lib/database_consistency/writers/autofix/templates/missing_foreign_key.tt
189
195
  - lib/database_consistency/writers/autofix/templates/null_constraint_missing.tt
190
196
  - lib/database_consistency/writers/autofix/templates/redundant_index.tt
191
197
  - lib/database_consistency/writers/autofix_writer.rb
192
198
  - lib/database_consistency/writers/base_writer.rb
199
+ - lib/database_consistency/writers/simple/association_missing_index.rb
200
+ - lib/database_consistency/writers/simple/association_missing_null_constraint.rb
193
201
  - lib/database_consistency/writers/simple/base.rb
194
202
  - lib/database_consistency/writers/simple/error_message.rb
203
+ - lib/database_consistency/writers/simple/has_one_missing_unique_index.rb
195
204
  - lib/database_consistency/writers/simple/inconsistent_types.rb
205
+ - lib/database_consistency/writers/simple/length_validator_greater_limit.rb
206
+ - lib/database_consistency/writers/simple/length_validator_lower_limit.rb
207
+ - lib/database_consistency/writers/simple/length_validator_missing.rb
208
+ - lib/database_consistency/writers/simple/missing_foreign_key.rb
209
+ - lib/database_consistency/writers/simple/missing_unique_index.rb
210
+ - lib/database_consistency/writers/simple/missing_uniqueness_validation.rb
196
211
  - lib/database_consistency/writers/simple/null_constraint_association_misses_validator.rb
212
+ - lib/database_consistency/writers/simple/null_constraint_misses_validator.rb
213
+ - lib/database_consistency/writers/simple/null_constraint_missing.rb
214
+ - lib/database_consistency/writers/simple/possible_null.rb
197
215
  - lib/database_consistency/writers/simple/redundant_index.rb
198
216
  - lib/database_consistency/writers/simple/redundant_unique_index.rb
217
+ - lib/database_consistency/writers/simple/small_primary_key.rb
199
218
  - lib/database_consistency/writers/simple_writer.rb
200
219
  - lib/database_consistency/writers/todo_writer.rb
201
220
  homepage: https://github.com/djezzzl/database_consistency