database_consistency 0.8.8 → 0.8.13
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 +4 -4
- data/lib/database_consistency.rb +4 -0
- data/lib/database_consistency/checkers/association_checkers/foreign_key_type_checker.rb +1 -1
- data/lib/database_consistency/checkers/index_checkers/index_checker.rb +23 -0
- data/lib/database_consistency/checkers/index_checkers/unique_index_checker.rb +47 -0
- data/lib/database_consistency/checkers/validator_checkers/missing_unique_index_checker.rb +4 -33
- data/lib/database_consistency/helper.rb +34 -0
- data/lib/database_consistency/processors/base_processor.rb +2 -1
- data/lib/database_consistency/processors/indexes_processor.rb +29 -0
- data/lib/database_consistency/templates/rails_defaults.yml +2 -0
- data/lib/database_consistency/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3d3bf88ec6fae8aac99d835defc6f02c0d16a8bf307c1ff8096c53fa252ef691
|
4
|
+
data.tar.gz: dd877669bd9a0de57fcf74969f16ba5d434997b36bcb4e73473e5242546ff6e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c3325319154f7e8420f10d39f1e3a1c325e776f4fda2ddee6e004655ee7526bc535bf8e9c958b79d5e41bb3a44a625b6c31eead26437b12b1649fa9fef3b136d
|
7
|
+
data.tar.gz: cee59e3274dc9a841915eb3baf9860cb749a84e1a1baa72e90bde23ba589f2a3d5d8473eda60dc544fa1cbe5fa1ab5496dc64d26ad5052b704ee04b1dbc91c9d
|
data/lib/database_consistency.rb
CHANGED
@@ -33,11 +33,15 @@ require 'database_consistency/checkers/validator_checkers/missing_unique_index_c
|
|
33
33
|
require 'database_consistency/checkers/validators_fraction_checkers/validators_fraction_checker'
|
34
34
|
require 'database_consistency/checkers/validators_fraction_checkers/column_presence_checker'
|
35
35
|
|
36
|
+
require 'database_consistency/checkers/index_checkers/index_checker'
|
37
|
+
require 'database_consistency/checkers/index_checkers/unique_index_checker'
|
38
|
+
|
36
39
|
require 'database_consistency/processors/base_processor'
|
37
40
|
require 'database_consistency/processors/associations_processor'
|
38
41
|
require 'database_consistency/processors/validators_processor'
|
39
42
|
require 'database_consistency/processors/columns_processor'
|
40
43
|
require 'database_consistency/processors/validators_fractions_processor'
|
44
|
+
require 'database_consistency/processors/indexes_processor'
|
41
45
|
|
42
46
|
# The root module
|
43
47
|
module DatabaseConsistency
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DatabaseConsistency
|
4
|
+
module Checkers
|
5
|
+
# The base class for table checkers
|
6
|
+
class IndexChecker < BaseChecker
|
7
|
+
attr_reader :model, :index
|
8
|
+
|
9
|
+
def initialize(model, index)
|
10
|
+
@model = model
|
11
|
+
@index = index
|
12
|
+
end
|
13
|
+
|
14
|
+
def column_or_attribute_name
|
15
|
+
@column_or_attribute_name ||= index.name.to_s
|
16
|
+
end
|
17
|
+
|
18
|
+
def table_or_model_name
|
19
|
+
@table_or_model_name ||= model.name.to_s
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DatabaseConsistency
|
4
|
+
module Checkers
|
5
|
+
# This class checks missing uniqueness validator
|
6
|
+
class UniqueIndexChecker < IndexChecker
|
7
|
+
# Message templates
|
8
|
+
VALIDATOR_MISSING = 'index is unique in the database but do not have uniqueness validator'
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
# We skip check when:
|
13
|
+
# - index is not unique
|
14
|
+
def preconditions
|
15
|
+
index.unique
|
16
|
+
end
|
17
|
+
|
18
|
+
# Table of possible statuses
|
19
|
+
# | validation | status |
|
20
|
+
# | ---------- | ------ |
|
21
|
+
# | provided | ok |
|
22
|
+
# | missing | fail |
|
23
|
+
#
|
24
|
+
def check
|
25
|
+
if valid?
|
26
|
+
report_template(:ok)
|
27
|
+
else
|
28
|
+
report_template(:fail, VALIDATOR_MISSING)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def valid?
|
33
|
+
uniqueness_validators = model.validators.select { |validator| validator.kind == :uniqueness }
|
34
|
+
|
35
|
+
uniqueness_validators.any? do |validator|
|
36
|
+
validator.attributes.any? do |attribute|
|
37
|
+
sorted_index_columns == Helper.sorted_uniqueness_validator_columns(attribute, validator, model)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def sorted_index_columns
|
43
|
+
@sorted_index_columns ||= Helper.extract_index_columns(index.columns).sort
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -7,7 +7,7 @@ module DatabaseConsistency
|
|
7
7
|
MISSING_INDEX = 'model should have proper unique index in the database'
|
8
8
|
|
9
9
|
def column_or_attribute_name
|
10
|
-
@column_or_attribute_name ||=
|
10
|
+
@column_or_attribute_name ||= Helper.uniqueness_validator_columns(attribute, validator, model).join('+')
|
11
11
|
end
|
12
12
|
|
13
13
|
private
|
@@ -33,41 +33,12 @@ module DatabaseConsistency
|
|
33
33
|
|
34
34
|
def unique_index
|
35
35
|
@unique_index ||= model.connection.indexes(model.table_name).find do |index|
|
36
|
-
index.unique && extract_index_columns(index.columns).sort ==
|
36
|
+
index.unique && Helper.extract_index_columns(index.columns).sort == sorted_uniqueness_validator_columns
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
return index_columns unless index_columns.is_a?(String)
|
43
|
-
|
44
|
-
index_columns.split(',')
|
45
|
-
.map(&:strip)
|
46
|
-
.map { |str| str.gsub(/lower\(/i, 'lower(') }
|
47
|
-
.map { |str| str.gsub(/\(([^)]+)\)::\w+/, '\1') }
|
48
|
-
end
|
49
|
-
|
50
|
-
def index_columns
|
51
|
-
@index_columns ||= ([wrapped_attribute_name] + scope_columns).map(&:to_s)
|
52
|
-
end
|
53
|
-
|
54
|
-
def scope_columns
|
55
|
-
@scope_columns ||= Array.wrap(validator.options[:scope]).map do |scope_item|
|
56
|
-
model._reflect_on_association(scope_item)&.foreign_key || scope_item
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def sorted_index_columns
|
61
|
-
@sorted_index_columns ||= index_columns.sort
|
62
|
-
end
|
63
|
-
|
64
|
-
# @return [String]
|
65
|
-
def wrapped_attribute_name
|
66
|
-
if validator.options[:case_sensitive].nil? || validator.options[:case_sensitive]
|
67
|
-
attribute
|
68
|
-
else
|
69
|
-
"lower(#{attribute})"
|
70
|
-
end
|
40
|
+
def sorted_uniqueness_validator_columns
|
41
|
+
@sorted_uniqueness_validator_columns ||= Helper.sorted_uniqueness_validator_columns(attribute, validator, model)
|
71
42
|
end
|
72
43
|
end
|
73
44
|
end
|
@@ -34,5 +34,39 @@ module DatabaseConsistency
|
|
34
34
|
|
35
35
|
associations
|
36
36
|
end
|
37
|
+
|
38
|
+
# @return [Array<String>]
|
39
|
+
def extract_index_columns(index_columns)
|
40
|
+
return index_columns unless index_columns.is_a?(String)
|
41
|
+
|
42
|
+
index_columns.split(',')
|
43
|
+
.map(&:strip)
|
44
|
+
.map { |str| str.gsub(/lower\(/i, 'lower(') }
|
45
|
+
.map { |str| str.gsub(/\(([^)]+)\)::\w+/, '\1') }
|
46
|
+
.map { |str| str.gsub(/'([^)]+)'::\w+/, '\1') }
|
47
|
+
end
|
48
|
+
|
49
|
+
def sorted_uniqueness_validator_columns(attribute, validator, model)
|
50
|
+
uniqueness_validator_columns(attribute, validator, model).sort
|
51
|
+
end
|
52
|
+
|
53
|
+
def uniqueness_validator_columns(attribute, validator, model)
|
54
|
+
([wrapped_attribute_name(attribute, validator)] + scope_columns(validator, model)).map(&:to_s)
|
55
|
+
end
|
56
|
+
|
57
|
+
def scope_columns(validator, model)
|
58
|
+
Array.wrap(validator.options[:scope]).map do |scope_item|
|
59
|
+
model._reflect_on_association(scope_item)&.foreign_key || scope_item
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# @return [String]
|
64
|
+
def wrapped_attribute_name(attribute, validator)
|
65
|
+
if validator.options[:case_sensitive].nil? || validator.options[:case_sensitive]
|
66
|
+
attribute
|
67
|
+
else
|
68
|
+
"lower(#{attribute})"
|
69
|
+
end
|
70
|
+
end
|
37
71
|
end
|
38
72
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DatabaseConsistency
|
4
|
+
module Processors
|
5
|
+
# The class to process indexes
|
6
|
+
class IndexesProcessor < BaseProcessor
|
7
|
+
CHECKERS = [
|
8
|
+
Checkers::UniqueIndexChecker
|
9
|
+
].freeze
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def check # rubocop:disable Metrics/AbcSize
|
14
|
+
Helper.parent_models.flat_map do |model|
|
15
|
+
next unless configuration.enabled?(model.name.to_s)
|
16
|
+
|
17
|
+
indexes = ActiveRecord::Base.connection.indexes(model.table_name)
|
18
|
+
|
19
|
+
indexes.flat_map do |index|
|
20
|
+
enabled_checkers.map do |checker_class|
|
21
|
+
checker = checker_class.new(model, index)
|
22
|
+
checker.report_if_enabled?(configuration)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end.compact
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
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: 0.8.
|
4
|
+
version: 0.8.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evgeniy Demin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -140,6 +140,8 @@ files:
|
|
140
140
|
- lib/database_consistency/checkers/column_checkers/length_constraint_checker.rb
|
141
141
|
- lib/database_consistency/checkers/column_checkers/null_constraint_checker.rb
|
142
142
|
- lib/database_consistency/checkers/column_checkers/primary_key_type_checker.rb
|
143
|
+
- lib/database_consistency/checkers/index_checkers/index_checker.rb
|
144
|
+
- lib/database_consistency/checkers/index_checkers/unique_index_checker.rb
|
143
145
|
- lib/database_consistency/checkers/validator_checkers/belongs_to_presence_checker.rb
|
144
146
|
- lib/database_consistency/checkers/validator_checkers/missing_unique_index_checker.rb
|
145
147
|
- lib/database_consistency/checkers/validator_checkers/validator_checker.rb
|
@@ -154,6 +156,7 @@ files:
|
|
154
156
|
- lib/database_consistency/processors/associations_processor.rb
|
155
157
|
- lib/database_consistency/processors/base_processor.rb
|
156
158
|
- lib/database_consistency/processors/columns_processor.rb
|
159
|
+
- lib/database_consistency/processors/indexes_processor.rb
|
157
160
|
- lib/database_consistency/processors/validators_fractions_processor.rb
|
158
161
|
- lib/database_consistency/processors/validators_processor.rb
|
159
162
|
- lib/database_consistency/rescue_error.rb
|