database_consistency 1.1.12 → 1.2.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: 908211c725197dadbe72f2f7c8f2f47d48a55ed546c57d2f512b9b2978fb325a
4
- data.tar.gz: 4b18e433573c598b25906dce98554516f3c54bacbd897b59c8f72c6d9577a53d
3
+ metadata.gz: f18ab981e7a995312fcefac4aad1673991c0ca74f83e892ed443b55399f73621
4
+ data.tar.gz: '0284902da44ea88322df42739eb9471212970ff4a2bde3ea91c491a0b3b6a8c6'
5
5
  SHA512:
6
- metadata.gz: 43ea449cc58c970f99deb81936461d2f267a107934ad93cfb1f73ef0e0a8e46c97d9ba5085a54538828d162ca06638ad35afb907fa51de661df30bad9527cefc
7
- data.tar.gz: 799f1975507dababf597ca140655377e90a1480af4422080349027b03ef7ef9dbade4125e95f317ef3d873706e82f1c24991c9c9600a08cb3dca3e6ff2bbc8e0
6
+ metadata.gz: 3765a63635638981d1a7389ed4d5f4a611d188c08281a13fc2ae5c435e4da8ad09a9a0f49511be596126d75caca322a3a7bd16309d27914adcfcb386a135223a
7
+ data.tar.gz: 6473f6990528f09bbb90e6e044b0e1c506b9c9586c65f2b76f8efaed68f1cb91d914703e11ba3747ce0663f9999e33065d7d5b0f5dbce44672a3ca33bd3be94f
@@ -7,6 +7,7 @@ module DatabaseConsistency
7
7
  attr_reader :model, :association
8
8
 
9
9
  def initialize(model, association)
10
+ super()
10
11
  @model = model
11
12
  @association = association
12
13
  end
@@ -6,6 +6,7 @@ module DatabaseConsistency
6
6
  class MissingIndexChecker < AssociationChecker
7
7
  # Message templates
8
8
  MISSING_INDEX = 'associated model should have proper index in the database'
9
+ MISSING_UNIQUE_INDEX = 'associated model should have proper unique index in the database'
9
10
 
10
11
  private
11
12
 
@@ -28,6 +29,22 @@ module DatabaseConsistency
28
29
  # | persisted | ok |
29
30
  # | missing | fail |
30
31
  def check
32
+ if unique_has_one_association?
33
+ check_unique_has_one
34
+ else
35
+ check_remaining
36
+ end
37
+ end
38
+
39
+ def check_unique_has_one
40
+ if unique_index
41
+ report_template(:ok)
42
+ else
43
+ report_template(:fail, MISSING_UNIQUE_INDEX)
44
+ end
45
+ end
46
+
47
+ def check_remaining
31
48
  if index
32
49
  report_template(:ok)
33
50
  else
@@ -35,9 +52,19 @@ module DatabaseConsistency
35
52
  end
36
53
  end
37
54
 
55
+ def unique_has_one_association?
56
+ association.scope.nil? && association.macro == :has_one && !association.options[:as].present?
57
+ end
58
+
59
+ def unique_index
60
+ @unique_index ||= association.klass.connection.indexes(association.klass.table_name).find do |index|
61
+ index_keys(index) == association_keys && index.unique
62
+ end
63
+ end
64
+
38
65
  def index
39
66
  @index ||= association.klass.connection.indexes(association.klass.table_name).find do |index|
40
- index_keys(index) == association_keys
67
+ index_keys(index, limit: association_keys.size) == association_keys
41
68
  end
42
69
  end
43
70
 
@@ -45,10 +72,16 @@ module DatabaseConsistency
45
72
  @association_keys ||= [association.foreign_key, association.type].compact.map(&:to_s).sort
46
73
  end
47
74
 
48
- def index_keys(index)
75
+ def index_keys(index, limit: nil)
49
76
  return unless index.columns.is_a?(Array)
50
77
 
51
- index.columns[0...association_keys.size].sort
78
+ columns = index.columns
79
+
80
+ if limit
81
+ columns.first(limit).sort
82
+ else
83
+ columns
84
+ end
52
85
  end
53
86
  end
54
87
  end
@@ -19,7 +19,7 @@ module DatabaseConsistency
19
19
  # @param [Boolean] catch_errors
20
20
  #
21
21
  # @return [Hash, File, nil]
22
- def report(catch_errors = true)
22
+ def report(catch_errors: true)
23
23
  return unless preconditions
24
24
 
25
25
  @report ||= check
@@ -7,6 +7,7 @@ module DatabaseConsistency
7
7
  attr_reader :model, :column
8
8
 
9
9
  def initialize(model, column)
10
+ super()
10
11
  @model = model
11
12
  @column = column
12
13
  end
@@ -7,6 +7,7 @@ module DatabaseConsistency
7
7
  attr_reader :model, :index
8
8
 
9
9
  def initialize(model, index)
10
+ super()
10
11
  @model = model
11
12
  @index = index
12
13
  end
@@ -7,6 +7,7 @@ module DatabaseConsistency
7
7
  attr_reader :model, :attribute, :validator
8
8
 
9
9
  def initialize(model, attribute, validator)
10
+ super()
10
11
  @model = model
11
12
  @attribute = attribute
12
13
  @validator = validator
@@ -7,6 +7,7 @@ module DatabaseConsistency
7
7
  attr_reader :model, :attribute, :validators
8
8
 
9
9
  def initialize(model, attribute, validators)
10
+ super()
10
11
  @model = model
11
12
  @attribute = attribute
12
13
  @validators = validators.select(&method(:filter))
@@ -37,22 +37,30 @@ module DatabaseConsistency
37
37
  def enabled?(*path)
38
38
  current = configuration
39
39
 
40
+ value = global_enabling
41
+
40
42
  path.each do |key|
41
43
  current = current[key.to_s]
42
- return true unless current.is_a?(Hash)
44
+ return value unless current.is_a?(Hash)
43
45
 
44
46
  next if current['enabled'].nil?
45
47
 
46
- return false unless current['enabled']
48
+ value = current['enabled']
47
49
  end
48
50
 
49
- true
51
+ value
50
52
  end
51
53
 
52
54
  private
53
55
 
54
56
  attr_reader :configuration
55
57
 
58
+ def global_enabling
59
+ value = configuration.dig('DatabaseConsistencyCheckers', 'All', 'enabled')
60
+
61
+ value.nil? ? true : value
62
+ end
63
+
56
64
  def load_yaml_config_file(filepath)
57
65
  if YAML.respond_to?(:safe_load_file)
58
66
  YAML.safe_load_file(filepath, aliases: true)
@@ -14,7 +14,7 @@ module DatabaseConsistency
14
14
 
15
15
  # @param [String] type
16
16
  def initialize(type)
17
- @type = type
17
+ @type = type.downcase
18
18
  end
19
19
 
20
20
  # @return [String]
@@ -23,8 +23,10 @@ module DatabaseConsistency
23
23
 
24
24
  # Returns list of models to check
25
25
  def models
26
- ActiveRecord::Base.descendants.delete_if(&:abstract_class?).delete_if do |klass|
27
- !klass.connection.table_exists?(klass.table_name) || klass.name.include?('HABTM_')
26
+ ActiveRecord::Base.descendants.delete_if(&:abstract_class?).select do |klass|
27
+ klass.connection.table_exists?(klass.table_name) &&
28
+ !klass.name.include?('HABTM_') &&
29
+ project_klass?(klass)
28
30
  end
29
31
  end
30
32
 
@@ -35,6 +37,15 @@ module DatabaseConsistency
35
37
  end
36
38
  end
37
39
 
40
+ # @param klass [ActiveRecord::Base]
41
+ #
42
+ # @return [Boolean]
43
+ def project_klass?(klass)
44
+ return true unless Module.respond_to?(:const_source_location) && defined?(Bundler)
45
+
46
+ !Module.const_source_location(klass.to_s).first.to_s.include?(Bundler.bundle_path.to_s)
47
+ end
48
+
38
49
  # @return [Boolean]
39
50
  def check_inclusion?(array, element)
40
51
  array.include?(element.to_s) || array.include?(element.to_sym)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DatabaseConsistency
4
- VERSION = '1.1.12'
4
+ VERSION = '1.2.0'
5
5
  end
@@ -12,6 +12,12 @@ module DatabaseConsistency
12
12
  red: "\e[31m"
13
13
  }.freeze
14
14
 
15
+ COLOR_BY_STATUS = {
16
+ ok: :green,
17
+ warning: :yellow,
18
+ fail: :red
19
+ }.freeze
20
+
15
21
  def write
16
22
  results.each do |result|
17
23
  next unless write?(result.status)
@@ -31,11 +37,7 @@ module DatabaseConsistency
31
37
  end
32
38
 
33
39
  def status_text(result)
34
- color = case result.status
35
- when :ok then :green
36
- when :warning then :yellow
37
- when :fail then :red
38
- end
40
+ color = COLOR_BY_STATUS[result.status]
39
41
 
40
42
  colorize(result.status, color)
41
43
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: database_consistency
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.12
4
+ version: 1.2.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-01-23 00:00:00.000000000 Z
11
+ date: 2022-09-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -199,7 +199,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
199
199
  - !ruby/object:Gem::Version
200
200
  version: '0'
201
201
  requirements: []
202
- rubygems_version: 3.2.22
202
+ rubygems_version: 3.3.21
203
203
  signing_key:
204
204
  specification_version: 4
205
205
  summary: Provide an easy way to check the consistency of the database constraints