database_consistency 1.1.12 → 1.2.0

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