database_consistency 2.0.8 → 2.1.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 +4 -4
- data/lib/database_consistency/checkers/association_checkers/association_checker.rb +7 -0
- data/lib/database_consistency/checkers/association_checkers/foreign_key_checker.rb +2 -7
- data/lib/database_consistency/checkers/association_checkers/missing_dependent_destroy_checker.rb +60 -0
- data/lib/database_consistency/checkers/validator_checkers/missing_unique_index_checker.rb +9 -1
- data/lib/database_consistency/version.rb +1 -1
- data/lib/database_consistency/writers/simple/missing_dependent_destroy.rb +22 -0
- data/lib/database_consistency.rb +2 -0
- metadata +5 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 347875b9be8806850702674f72e235f318f9c307bc915370fa940f3c23476e1d
|
|
4
|
+
data.tar.gz: b19f093bc18afb4be2f47b3309f9d8bd09f786b774d9226421e2856ec87a63e4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: af8ea0a3e3e1ab9069a9db551601127d2fb82899a315eb40d2bdab4698f134704e248dce76826924b598755f94eb00280ebc15374189987da81cc748a9565ced
|
|
7
|
+
data.tar.gz: a2348924c764f4ee1d1d880aff03e3414ba9f2c62c4aba2c8b415bc52e92a282a6608e5da768b90468fcae0cf7b618bf4469fc86c0a1c1c5a6b7c2b301ca6079
|
|
@@ -23,6 +23,13 @@ module DatabaseConsistency
|
|
|
23
23
|
def table_or_model_name
|
|
24
24
|
@table_or_model_name ||= model.name.to_s
|
|
25
25
|
end
|
|
26
|
+
|
|
27
|
+
def foreign_key_exists? # rubocop:disable Metrics/AbcSize
|
|
28
|
+
model.connection.foreign_keys(model.table_name).any? do |foreign_key|
|
|
29
|
+
(Helper.extract_columns(association.foreign_key.to_s) - Array.wrap(foreign_key.column)).empty? &&
|
|
30
|
+
foreign_key.to_table == association.klass.table_name
|
|
31
|
+
end
|
|
32
|
+
end
|
|
26
33
|
end
|
|
27
34
|
end
|
|
28
35
|
end
|
|
@@ -42,13 +42,8 @@ module DatabaseConsistency
|
|
|
42
42
|
# | ----------- | ------ |
|
|
43
43
|
# | persisted | ok |
|
|
44
44
|
# | missing | fail |
|
|
45
|
-
def check
|
|
46
|
-
|
|
47
|
-
(Helper.extract_columns(association.foreign_key.to_s) - Array.wrap(fk.column)).empty? &&
|
|
48
|
-
fk.to_table == association.klass.table_name
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
if fk_exist
|
|
45
|
+
def check
|
|
46
|
+
if foreign_key_exists?
|
|
52
47
|
report_template(:ok)
|
|
53
48
|
else
|
|
54
49
|
report_template(:fail, error_slug: :missing_foreign_key)
|
data/lib/database_consistency/checkers/association_checkers/missing_dependent_destroy_checker.rb
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module DatabaseConsistency
|
|
4
|
+
module Checkers
|
|
5
|
+
# This class checks for models that need a dependent destroy association
|
|
6
|
+
class MissingDependentDestroyChecker < AssociationChecker
|
|
7
|
+
Report = ReportBuilder.define(
|
|
8
|
+
DatabaseConsistency::Report,
|
|
9
|
+
:model_name,
|
|
10
|
+
:attribute_name
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
DEPENDENT_OPTIONS = %i[destroy delete delete_all nullify].freeze
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def preconditions
|
|
18
|
+
association.belongs_to? && foreign_key_exists?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def check
|
|
22
|
+
if dependent_destroy_exists? || cascade?
|
|
23
|
+
report_template(:ok)
|
|
24
|
+
else
|
|
25
|
+
report_template(:fail, error_slug: :missing_dependent_destroy)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def dependent_destroy_exists?
|
|
30
|
+
association.class_name.constantize.reflect_on_all_associations.any? do |association|
|
|
31
|
+
%i[has_many has_one].include?(association.macro) &&
|
|
32
|
+
DEPENDENT_OPTIONS.include?(association.options[:dependent]) &&
|
|
33
|
+
association.table_name == model.table_name
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def foreign_key
|
|
38
|
+
association.klass
|
|
39
|
+
.connection
|
|
40
|
+
.foreign_keys(model.table_name)
|
|
41
|
+
.find { |fk| fk.column == association.foreign_key.to_s }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def cascade?
|
|
45
|
+
%i[cascade nullify].include? foreign_key.options[:on_delete]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def report_template(status, error_slug: nil)
|
|
49
|
+
Report.new(
|
|
50
|
+
status: status,
|
|
51
|
+
error_message: nil,
|
|
52
|
+
error_slug: error_slug,
|
|
53
|
+
model_name: association.class_name,
|
|
54
|
+
attribute_name: model.table_name,
|
|
55
|
+
**report_attributes
|
|
56
|
+
)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -28,7 +28,7 @@ module DatabaseConsistency
|
|
|
28
28
|
# | persisted | ok |
|
|
29
29
|
# | missing | fail |
|
|
30
30
|
def check
|
|
31
|
-
if unique_index
|
|
31
|
+
if unique_index || primary_key_covers_validation?
|
|
32
32
|
report_template(:ok)
|
|
33
33
|
else
|
|
34
34
|
report_template(:fail, error_slug: :missing_unique_index)
|
|
@@ -52,6 +52,14 @@ module DatabaseConsistency
|
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
+
def primary_key_covers_validation?
|
|
56
|
+
primary_key = model.connection.primary_key(model.table_name)
|
|
57
|
+
|
|
58
|
+
return false if primary_key.blank?
|
|
59
|
+
|
|
60
|
+
sorted_uniqueness_validator_columns == Helper.extract_columns(primary_key).sort
|
|
61
|
+
end
|
|
62
|
+
|
|
55
63
|
def sorted_uniqueness_validator_columns
|
|
56
64
|
@sorted_uniqueness_validator_columns ||= Helper.sorted_uniqueness_validator_columns(attribute, validator, model)
|
|
57
65
|
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module DatabaseConsistency
|
|
4
|
+
module Writers
|
|
5
|
+
module Simple
|
|
6
|
+
class MissingDependentDestroy < Base # :nodoc:
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
def template
|
|
10
|
+
'should have a corresponding has_one/has_many association with dependent option (destroy, delete, delete_all, nullify) or a foreign key with on_delete (cascade, nullify)' # rubocop:disable Layout/LineLength
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def unique_attributes
|
|
14
|
+
{
|
|
15
|
+
model_name: report.model_name,
|
|
16
|
+
attribute_name: report.attribute_name
|
|
17
|
+
}
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/database_consistency.rb
CHANGED
|
@@ -43,6 +43,7 @@ require 'database_consistency/writers/simple/three_state_boolean'
|
|
|
43
43
|
require 'database_consistency/writers/simple/missing_association_class'
|
|
44
44
|
require 'database_consistency/writers/simple/missing_table'
|
|
45
45
|
require 'database_consistency/writers/simple/implicit_order_column_missing'
|
|
46
|
+
require 'database_consistency/writers/simple/missing_dependent_destroy'
|
|
46
47
|
require 'database_consistency/writers/simple_writer'
|
|
47
48
|
|
|
48
49
|
require 'database_consistency/writers/autofix/helpers/migration'
|
|
@@ -83,6 +84,7 @@ require 'database_consistency/checkers/association_checkers/foreign_key_checker'
|
|
|
83
84
|
require 'database_consistency/checkers/association_checkers/foreign_key_type_checker'
|
|
84
85
|
require 'database_consistency/checkers/association_checkers/foreign_key_cascade_checker'
|
|
85
86
|
require 'database_consistency/checkers/association_checkers/missing_association_class_checker'
|
|
87
|
+
require 'database_consistency/checkers/association_checkers/missing_dependent_destroy_checker'
|
|
86
88
|
|
|
87
89
|
require 'database_consistency/checkers/column_checkers/column_checker'
|
|
88
90
|
require 'database_consistency/checkers/column_checkers/null_constraint_checker'
|
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: 2.0
|
|
4
|
+
version: 2.1.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: 2025-
|
|
11
|
+
date: 2025-12-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|
|
@@ -151,6 +151,7 @@ files:
|
|
|
151
151
|
- lib/database_consistency/checkers/association_checkers/foreign_key_checker.rb
|
|
152
152
|
- lib/database_consistency/checkers/association_checkers/foreign_key_type_checker.rb
|
|
153
153
|
- lib/database_consistency/checkers/association_checkers/missing_association_class_checker.rb
|
|
154
|
+
- lib/database_consistency/checkers/association_checkers/missing_dependent_destroy_checker.rb
|
|
154
155
|
- lib/database_consistency/checkers/association_checkers/missing_index_checker.rb
|
|
155
156
|
- lib/database_consistency/checkers/base_checker.rb
|
|
156
157
|
- lib/database_consistency/checkers/column_checkers/column_checker.rb
|
|
@@ -225,6 +226,7 @@ files:
|
|
|
225
226
|
- lib/database_consistency/writers/simple/length_validator_lower_limit.rb
|
|
226
227
|
- lib/database_consistency/writers/simple/length_validator_missing.rb
|
|
227
228
|
- lib/database_consistency/writers/simple/missing_association_class.rb
|
|
229
|
+
- lib/database_consistency/writers/simple/missing_dependent_destroy.rb
|
|
228
230
|
- lib/database_consistency/writers/simple/missing_foreign_key.rb
|
|
229
231
|
- lib/database_consistency/writers/simple/missing_foreign_key_cascade.rb
|
|
230
232
|
- lib/database_consistency/writers/simple/missing_table.rb
|
|
@@ -273,7 +275,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
273
275
|
- !ruby/object:Gem::Version
|
|
274
276
|
version: '0'
|
|
275
277
|
requirements: []
|
|
276
|
-
rubygems_version: 3.
|
|
278
|
+
rubygems_version: 3.3.22
|
|
277
279
|
signing_key:
|
|
278
280
|
specification_version: 4
|
|
279
281
|
summary: Provide an easy way to check the consistency of the database constraints
|