database_consistency 1.3.4 → 1.3.6

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