database_consistency 1.3.3 → 1.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (24) hide show
  1. checksums.yaml +4 -4
  2. data/lib/database_consistency/checkers/association_checkers/foreign_key_checker.rb +0 -9
  3. data/lib/database_consistency/checkers/association_checkers/foreign_key_type_checker.rb +0 -9
  4. data/lib/database_consistency/checkers/column_checkers/null_constraint_checker.rb +0 -4
  5. data/lib/database_consistency/checkers/index_checkers/redundant_index_checker.rb +0 -4
  6. data/lib/database_consistency/checkers/index_checkers/redundant_unique_index_checker.rb +6 -8
  7. data/lib/database_consistency/checkers/validators_fraction_checkers/column_presence_checker.rb +0 -4
  8. data/lib/database_consistency/report.rb +0 -7
  9. data/lib/database_consistency/version.rb +1 -1
  10. data/lib/database_consistency/writers/autofix/migration_base.rb +5 -1
  11. data/lib/database_consistency/writers/autofix/missing_foreign_key.rb +9 -0
  12. data/lib/database_consistency/writers/autofix/null_constraint_missing.rb +7 -0
  13. data/lib/database_consistency/writers/autofix/redundant_index.rb +6 -0
  14. data/lib/database_consistency/writers/autofix_writer.rb +14 -11
  15. data/lib/database_consistency/writers/simple/base.rb +67 -0
  16. data/lib/database_consistency/writers/simple/error_message.rb +15 -0
  17. data/lib/database_consistency/writers/simple/inconsistent_types.rb +24 -0
  18. data/lib/database_consistency/writers/simple/null_constraint_association_misses_validator.rb +21 -0
  19. data/lib/database_consistency/writers/simple/redundant_index.rb +21 -0
  20. data/lib/database_consistency/writers/simple/redundant_unique_index.rb +21 -0
  21. data/lib/database_consistency/writers/simple_writer.rb +24 -54
  22. data/lib/database_consistency.rb +8 -3
  23. metadata +7 -2
  24. data/lib/database_consistency/writers/helpers/pipes.rb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 857156332ffa36d32216953b8bd1f798ae27dcb2037e873c93d08fa55a01bd47
4
- data.tar.gz: f1aa19a34377de90e606b1e8272d9444992e44f6487c0ac28d913298d5ef6df9
3
+ metadata.gz: 1f1aad5cf1e4812b31d9bc7df0402f64dd32bb7ebdb9ab4ec7bf41bb195622dc
4
+ data.tar.gz: 1fc95e58bd89e9faf0004d7faf5cc2635d5432785d2e1a57d9965e413abf4c41
5
5
  SHA512:
6
- metadata.gz: 635ac9cfa1426f77ec59647e7282887fcfc81ec2db8217a545f791383bc1e3538f8f2e5bcb55c1aedee194b27287063a0ee330ffafe0068a7c219f2350a421b9
7
- data.tar.gz: f72cf3ef8ac71296984002d798b895740fc15ec91e582503fde012d8b58986956e36bd41bfae5453abb374da27a20f92bbcf96fbfe2abdddf3fe8f2569be3f48
6
+ metadata.gz: 6d5d98750608c54e20a5f6990b54c37df89717d7009d46b099b62695b90c2a29ab44f35dab299c1e3e0f83ff4d77f5709e6a42aa7130190fcbb1807b5a6628b9
7
+ data.tar.gz: ff7a4d0fa92518ed33393c8e1614852ef9ec168ee5a4ac857a653881a268511ad877b982633553e7341ce8a740dbf7ae402002e991210784614e397dbe07ed36
@@ -14,15 +14,6 @@ module DatabaseConsistency
14
14
  @foreign_table = foreign_table
15
15
  @foreign_key = foreign_key
16
16
  end
17
-
18
- def attributes
19
- super.merge(
20
- primary_table: primary_table,
21
- primary_key: primary_key,
22
- foreign_table: foreign_table,
23
- foreign_key: foreign_key
24
- )
25
- end
26
17
  end
27
18
 
28
19
  private
@@ -14,15 +14,6 @@ module DatabaseConsistency
14
14
  @pk_name = pk_name
15
15
  @pk_type = pk_type
16
16
  end
17
-
18
- def attributes
19
- super.merge(
20
- fk_name: fk_name,
21
- fk_type: fk_type,
22
- pk_name: pk_name,
23
- pk_type: pk_type
24
- )
25
- end
26
17
  end
27
18
 
28
19
  private
@@ -11,10 +11,6 @@ module DatabaseConsistency
11
11
  super(**args)
12
12
  @association_name = association_name
13
13
  end
14
-
15
- def attributes
16
- super.merge(association_name: association_name)
17
- end
18
14
  end
19
15
 
20
16
  private
@@ -12,10 +12,6 @@ module DatabaseConsistency
12
12
  @covered_index_name = covered_index_name
13
13
  @index_name = index_name
14
14
  end
15
-
16
- def attributes
17
- super.merge(covered_index_name: covered_index_name, index_name: index_name)
18
- end
19
15
  end
20
16
 
21
17
  private
@@ -5,15 +5,12 @@ module DatabaseConsistency
5
5
  # This class checks redundant database indexes
6
6
  class RedundantUniqueIndexChecker < IndexChecker
7
7
  class Report < DatabaseConsistency::Report # :nodoc:
8
- attr_reader :index_name
8
+ attr_reader :index_name, :covered_index_name
9
9
 
10
- def initialize(index_name:, **args)
10
+ def initialize(covered_index_name:, index_name:, **args)
11
11
  super(**args)
12
12
  @index_name = index_name
13
- end
14
-
15
- def attributes
16
- super.merge(index_name: index_name)
13
+ @covered_index_name = covered_index_name
17
14
  end
18
15
  end
19
16
 
@@ -31,13 +28,14 @@ module DatabaseConsistency
31
28
  # | provided | ok |
32
29
  # | redundant | fail |
33
30
  #
34
- def check
31
+ def check # rubocop:disable Metrics/MethodLength
35
32
  if covered_by_index
36
33
  Report.new(
37
34
  status: :fail,
38
35
  error_slug: :redundant_unique_index,
39
36
  error_message: nil,
40
- index_name: covered_by_index.name,
37
+ index_name: index.name,
38
+ covered_index_name: covered_by_index.name,
41
39
  **report_attributes
42
40
  )
43
41
  else
@@ -14,10 +14,6 @@ module DatabaseConsistency
14
14
  @table_name = table_name
15
15
  @column_name = column_name
16
16
  end
17
-
18
- def attributes
19
- super.merge(table_name: table_name, column_name: column_name)
20
- end
21
17
  end
22
18
 
23
19
  private
@@ -12,12 +12,5 @@ module DatabaseConsistency
12
12
  @error_slug = error_slug
13
13
  @error_message = error_message
14
14
  end
15
-
16
- def attributes
17
- {
18
- error_slug: error_slug,
19
- error_message: error_message
20
- }
21
- end
22
15
  end
23
16
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DatabaseConsistency
4
- VERSION = '1.3.3'
4
+ VERSION = '1.3.4'
5
5
  end
@@ -10,10 +10,14 @@ module DatabaseConsistency
10
10
  File.write(migration_path(migration_name), migration)
11
11
  end
12
12
 
13
+ def attributes
14
+ {}
15
+ end
16
+
13
17
  private
14
18
 
15
19
  def migration
16
- File.read(template_path) % report.attributes.merge(migration_configuration(migration_name))
20
+ File.read(template_path) % attributes.merge(migration_configuration(migration_name))
17
21
  end
18
22
  end
19
23
  end
@@ -4,6 +4,15 @@ module DatabaseConsistency
4
4
  module Writers
5
5
  module Autofix
6
6
  class MissingForeignKey < MigrationBase # :nodoc:
7
+ def attributes
8
+ {
9
+ foreign_table: report.foreign_table,
10
+ foreign_key: report.foreign_key,
11
+ primary_table: report.primary_table,
12
+ primary_key: report.primary_key
13
+ }
14
+ end
15
+
7
16
  private
8
17
 
9
18
  def migration_name
@@ -4,6 +4,13 @@ module DatabaseConsistency
4
4
  module Writers
5
5
  module Autofix
6
6
  class NullConstraintMissing < MigrationBase # :nodoc:
7
+ def attributes
8
+ {
9
+ table_name: report.table_name,
10
+ column_name: report.column_name
11
+ }
12
+ end
13
+
7
14
  private
8
15
 
9
16
  def migration_name
@@ -4,6 +4,12 @@ module DatabaseConsistency
4
4
  module Writers
5
5
  module Autofix
6
6
  class RedundantIndex < MigrationBase # :nodoc:
7
+ def attributes
8
+ {
9
+ index_name: report.index_name
10
+ }
11
+ end
12
+
7
13
  private
8
14
 
9
15
  def migration_name
@@ -9,32 +9,35 @@ module DatabaseConsistency
9
9
  missing_foreign_key: Autofix::MissingForeignKey,
10
10
  null_constraint_missing: Autofix::NullConstraintMissing,
11
11
  association_missing_null_constraint: Autofix::NullConstraintMissing,
12
- redundant_index: Autofix::RedundantIndex
12
+ redundant_index: Autofix::RedundantIndex,
13
+ redundant_unique_index: Autofix::RedundantIndex
13
14
  }.freeze
14
15
 
15
16
  def write
16
- reports.each do |report|
17
- next unless fix?(report)
18
-
19
- fix(report)
20
- end
17
+ unique_generators.each(&:fix!)
21
18
  end
22
19
 
23
20
  private
24
21
 
25
- def reports
26
- results.then(&Helpers::Pipes.method(:unique))
22
+ def unique_generators
23
+ results
24
+ .select(&method(:fix?))
25
+ .map(&method(:generator))
26
+ .compact
27
+ .uniq(&method(:unique_key))
27
28
  end
28
29
 
29
30
  def fix?(report)
30
31
  report.status == :fail
31
32
  end
32
33
 
33
- def fix(report)
34
+ def generator(report)
34
35
  klass = SLUG_TO_GENERATOR[report.error_slug]
35
- return unless klass
36
+ klass&.new(report)
37
+ end
36
38
 
37
- klass.new(report).fix!
39
+ def unique_key(report)
40
+ [report.class, report.attributes]
38
41
  end
39
42
  end
40
43
  end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Simple
6
+ class Base # :nodoc:
7
+ COLORS = {
8
+ blue: "\e[34m",
9
+ yellow: "\e[33m",
10
+ green: "\e[32m",
11
+ red: "\e[31m"
12
+ }.freeze
13
+
14
+ COLOR_BY_STATUS = {
15
+ ok: :green,
16
+ warning: :yellow,
17
+ fail: :red
18
+ }.freeze
19
+
20
+ def self.with(text)
21
+ Class.new(self) do
22
+ define_method :template do
23
+ text
24
+ end
25
+ end
26
+ end
27
+
28
+ attr_reader :report, :config
29
+
30
+ def initialize(report, config:)
31
+ @report = report
32
+ @config = config
33
+ end
34
+
35
+ def msg
36
+ "#{report.checker_name} #{status_text} #{key_text} #{message_text}"
37
+ end
38
+
39
+ private
40
+
41
+ def message_text
42
+ template % attributes
43
+ end
44
+
45
+ def attributes
46
+ {}
47
+ end
48
+
49
+ def key_text
50
+ "#{colorize(report.table_or_model_name, :blue)} #{colorize(report.column_or_attribute_name, :yellow)}"
51
+ end
52
+
53
+ def colorize(text, color)
54
+ return text unless config.colored? && color
55
+
56
+ "#{COLORS[color]}#{text}\e[0m"
57
+ end
58
+
59
+ def status_text
60
+ color = COLOR_BY_STATUS[report.status]
61
+
62
+ colorize(report.status, color)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Simple
6
+ class ErrorMessage < Base # :nodoc:
7
+ private
8
+
9
+ def template
10
+ report.error_message || ''
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Simple
6
+ class InconsistentTypes < Base # :nodoc:
7
+ private
8
+
9
+ def template
10
+ "foreign key %<fk_name>s with type %<fk_type>s doesn't cover primary key %<pk_name>s with type %<pk_type>s"
11
+ end
12
+
13
+ def attributes
14
+ {
15
+ fk_name: report.fk_name,
16
+ fk_type: report.fk_type,
17
+ pk_name: report.pk_name,
18
+ pk_type: report.pk_type
19
+ }
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Simple
6
+ class NullConstraintAssociationMissesValidator < Base # :nodoc:
7
+ private
8
+
9
+ def template
10
+ 'column is required in the database but do not have presence validator for association %<association_name>s'
11
+ end
12
+
13
+ def attributes
14
+ {
15
+ association_name: report.association_name
16
+ }
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Simple
6
+ class RedundantIndex < Base # :nodoc:
7
+ private
8
+
9
+ def template
10
+ 'index is redundant as %<covered_index_name>s covers it'
11
+ end
12
+
13
+ def attributes
14
+ {
15
+ covered_index_name: report.covered_index_name
16
+ }
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Simple
6
+ class RedundantUniqueIndex < Base # :nodoc:
7
+ private
8
+
9
+ def template
10
+ 'index uniqueness is redundant as %<covered_index_name>s covers it'
11
+ end
12
+
13
+ def attributes
14
+ {
15
+ covered_index_name: report.covered_index_name
16
+ }
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -5,75 +5,45 @@ module DatabaseConsistency
5
5
  module Writers
6
6
  # The simplest formatter
7
7
  class SimpleWriter < BaseWriter
8
- COLORS = {
9
- blue: "\e[34m",
10
- yellow: "\e[33m",
11
- green: "\e[32m",
12
- red: "\e[31m"
13
- }.freeze
14
-
15
- COLOR_BY_STATUS = {
16
- ok: :green,
17
- warning: :yellow,
18
- fail: :red
19
- }.freeze
20
-
21
- SLUG_TO_MESSAGE = {
22
- missing_foreign_key: 'should have foreign key in the database',
23
- inconsistent_types: "foreign key %<fk_name>s with type %<fk_type>s doesn't cover primary key %<pk_name>s with type %<pk_type>s", # rubocop:disable Layout/LineLength
24
- has_one_missing_unique_index: 'associated model should have proper unique index in the database',
25
- association_missing_index: 'associated model should have proper index in the database',
26
- length_validator_missing: 'column has limit in the database but do not have length validator',
27
- length_validator_greater_limit: 'column has greater limit in the database than in length validator',
28
- length_validator_lower_limit: 'column has lower limit in the database than in length validator',
29
- null_constraint_association_misses_validator: 'column is required in the database but do not have presence validator for association %<association_name>s', # rubocop:disable Layout/LineLength
30
- null_constraint_misses_validator: 'column is required in the database but do not have presence validator',
31
- small_primary_key: 'column has int/serial type but recommended to have bigint/bigserial/uuid',
32
- redundant_index: 'index is redundant as %<covered_index_name>s covers it',
33
- redundant_unique_index: 'index uniqueness is redundant as %<index_name>s covers it',
34
- missing_uniqueness_validation: 'index is unique in the database but do not have uniqueness validator',
35
- missing_unique_index: 'model should have proper unique index in the database',
36
- possible_null: 'column is required but there is possible null value insert',
37
- null_constraint_missing: 'column should be required in the database',
38
- association_missing_null_constraint: 'association foreign key column should be required in the database'
8
+ SLUG_TO_WRITER = {
9
+ missing_foreign_key: Simple::Base.with('should have foreign key in the database'),
10
+ 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
23
+ null_constraint_association_misses_validator: Simple::NullConstraintAssociationMissesValidator,
24
+ redundant_index: Simple::RedundantIndex,
25
+ redundant_unique_index: Simple::RedundantUniqueIndex
39
26
  }.freeze
40
27
 
41
28
  def write
42
29
  results.each do |result|
43
30
  next unless write?(result.status)
44
31
 
45
- puts msg(result)
32
+ writer = writer(result)
33
+
34
+ puts writer.msg
46
35
  end
47
36
  end
48
37
 
49
38
  private
50
39
 
51
- def msg(result)
52
- "#{result.checker_name} #{status_text(result)} #{key_text(result)} #{message_text(result)}"
53
- end
54
-
55
40
  def write?(status)
56
41
  status == :fail || config.debug?
57
42
  end
58
43
 
59
- def message_text(result)
60
- (SLUG_TO_MESSAGE[result.error_slug] || result.error_message || '') % result.attributes
61
- end
62
-
63
- def key_text(result)
64
- "#{colorize(result.table_or_model_name, :blue)} #{colorize(result.column_or_attribute_name, :yellow)}"
65
- end
66
-
67
- def status_text(result)
68
- color = COLOR_BY_STATUS[result.status]
69
-
70
- colorize(result.status, color)
71
- end
72
-
73
- def colorize(text, color)
74
- return text unless config.colored? && color
75
-
76
- "#{COLORS[color]}#{text}\e[0m"
44
+ def writer(report)
45
+ klass = SLUG_TO_WRITER[report.error_slug] || Simple::ErrorMessage
46
+ klass.new(report, config: config)
77
47
  end
78
48
  end
79
49
  end
@@ -9,12 +9,17 @@ require 'database_consistency/rescue_error'
9
9
  require 'database_consistency/errors'
10
10
  require 'database_consistency/report'
11
11
 
12
- require 'database_consistency/writers/helpers/pipes'
13
-
14
12
  require 'database_consistency/writers/base_writer'
15
- require 'database_consistency/writers/simple_writer'
16
13
  require 'database_consistency/writers/todo_writer'
17
14
 
15
+ require 'database_consistency/writers/simple/base'
16
+ require 'database_consistency/writers/simple/error_message'
17
+ require 'database_consistency/writers/simple/inconsistent_types'
18
+ require 'database_consistency/writers/simple/null_constraint_association_misses_validator'
19
+ require 'database_consistency/writers/simple/redundant_index'
20
+ require 'database_consistency/writers/simple/redundant_unique_index'
21
+ require 'database_consistency/writers/simple_writer'
22
+
18
23
  require 'database_consistency/writers/autofix/helpers/migration'
19
24
  require 'database_consistency/writers/autofix/base'
20
25
  require 'database_consistency/writers/autofix/migration_base'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: database_consistency
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.3
4
+ version: 1.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evgeniy Demin
@@ -190,7 +190,12 @@ files:
190
190
  - lib/database_consistency/writers/autofix/templates/redundant_index.tt
191
191
  - lib/database_consistency/writers/autofix_writer.rb
192
192
  - lib/database_consistency/writers/base_writer.rb
193
- - lib/database_consistency/writers/helpers/pipes.rb
193
+ - lib/database_consistency/writers/simple/base.rb
194
+ - lib/database_consistency/writers/simple/error_message.rb
195
+ - lib/database_consistency/writers/simple/inconsistent_types.rb
196
+ - lib/database_consistency/writers/simple/null_constraint_association_misses_validator.rb
197
+ - lib/database_consistency/writers/simple/redundant_index.rb
198
+ - lib/database_consistency/writers/simple/redundant_unique_index.rb
194
199
  - lib/database_consistency/writers/simple_writer.rb
195
200
  - lib/database_consistency/writers/todo_writer.rb
196
201
  homepage: https://github.com/djezzzl/database_consistency
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DatabaseConsistency
4
- module Writers
5
- module Helpers
6
- module Pipes # :nodoc:
7
- module_function
8
-
9
- def unique(reports)
10
- reports.uniq(&:attributes)
11
- end
12
- end
13
- end
14
- end
15
- end