database_consistency 1.3.5 → 1.3.7
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/foreign_key_checker.rb +22 -22
- data/lib/database_consistency/checkers/association_checkers/foreign_key_type_checker.rb +10 -16
- data/lib/database_consistency/checkers/association_checkers/missing_index_checker.rb +5 -9
- data/lib/database_consistency/checkers/column_checkers/null_constraint_checker.rb +16 -16
- data/lib/database_consistency/checkers/column_checkers/primary_key_type_checker.rb +20 -20
- data/lib/database_consistency/checkers/index_checkers/redundant_index_checker.rb +18 -18
- data/lib/database_consistency/checkers/index_checkers/redundant_unique_index_checker.rb +18 -18
- data/lib/database_consistency/checkers/validator_checkers/missing_unique_index_checker.rb +18 -18
- data/lib/database_consistency/checkers/validators_fraction_checkers/column_presence_checker.rb +16 -9
- data/lib/database_consistency/report.rb +9 -12
- data/lib/database_consistency/report_builder.rb +24 -0
- data/lib/database_consistency/version.rb +1 -1
- data/lib/database_consistency/writers/autofix_writer.rb +2 -2
- data/lib/database_consistency/writers/simple/association_missing_index.rb +22 -0
- data/lib/database_consistency/writers/simple/association_missing_null_constraint.rb +22 -0
- data/lib/database_consistency/writers/simple/base.rb +9 -1
- data/lib/database_consistency/writers/simple/{error_message.rb → default_message.rb} +5 -1
- data/lib/database_consistency/writers/simple/has_one_missing_unique_index.rb +23 -0
- data/lib/database_consistency/writers/simple/inconsistent_types.rb +10 -1
- data/lib/database_consistency/writers/simple/length_validator_greater_limit.rb +22 -0
- data/lib/database_consistency/writers/simple/length_validator_lower_limit.rb +22 -0
- data/lib/database_consistency/writers/simple/length_validator_missing.rb +22 -0
- data/lib/database_consistency/writers/simple/missing_foreign_key.rb +24 -0
- data/lib/database_consistency/writers/simple/missing_unique_index.rb +23 -0
- data/lib/database_consistency/writers/simple/missing_uniqueness_validation.rb +22 -0
- data/lib/database_consistency/writers/simple/null_constraint_association_misses_validator.rb +7 -0
- data/lib/database_consistency/writers/simple/null_constraint_misses_validator.rb +22 -0
- data/lib/database_consistency/writers/simple/null_constraint_missing.rb +22 -0
- data/lib/database_consistency/writers/simple/possible_null.rb +22 -0
- data/lib/database_consistency/writers/simple/redundant_index.rb +6 -0
- data/lib/database_consistency/writers/simple/redundant_unique_index.rb +6 -0
- data/lib/database_consistency/writers/simple/small_primary_key.rb +22 -0
- data/lib/database_consistency/writers/simple_writer.rb +28 -22
- data/lib/database_consistency.rb +15 -1
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3977b5e14b960051dad79361a32e435e511707612a269512fd42dcbac389216f
|
4
|
+
data.tar.gz: 95aba2661c7724aca4cee0e386b8f5e12e59f62b6444f35c66ebcabba2a6f9be
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d71ae7f118719222bfcdb11329d8f0be6ca5c62d8f54ca145cd08f26d982e7e7b0a1b848397b19aa4e4a4c35e88602be24fd384896ed58cf6221f83e7d87280c
|
7
|
+
data.tar.gz: 0b1efa4b1c268d3959eae583bd4b2e3dc6da2585ac64a6ebf4b4a83ad73710f1a0c704ff1fdee4e13c01b5170c41bf593f31bd77a7f6bea9b6d417fe892208d6
|
@@ -4,17 +4,13 @@ module DatabaseConsistency
|
|
4
4
|
module Checkers
|
5
5
|
# This class checks if non polymorphic +belongs_to+ association has foreign key constraint
|
6
6
|
class ForeignKeyChecker < AssociationChecker
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
@foreign_table = foreign_table
|
15
|
-
@foreign_key = foreign_key
|
16
|
-
end
|
17
|
-
end
|
7
|
+
Report = ReportBuilder.define(
|
8
|
+
DatabaseConsistency::Report,
|
9
|
+
:primary_table,
|
10
|
+
:primary_key,
|
11
|
+
:foreign_table,
|
12
|
+
:foreign_key
|
13
|
+
)
|
18
14
|
|
19
15
|
private
|
20
16
|
|
@@ -43,22 +39,26 @@ module DatabaseConsistency
|
|
43
39
|
# | ----------- | ------ |
|
44
40
|
# | persisted | ok |
|
45
41
|
# | missing | fail |
|
46
|
-
def check
|
42
|
+
def check
|
47
43
|
if model.connection.foreign_keys(model.table_name).find { |fk| fk.column == association.foreign_key.to_s }
|
48
44
|
report_template(:ok)
|
49
45
|
else
|
50
|
-
|
51
|
-
status: :fail,
|
52
|
-
error_message: nil,
|
53
|
-
error_slug: :missing_foreign_key,
|
54
|
-
primary_table: association.table_name.to_s,
|
55
|
-
primary_key: association.association_primary_key.to_s,
|
56
|
-
foreign_table: association.active_record.table_name.to_s,
|
57
|
-
foreign_key: association.foreign_key.to_s,
|
58
|
-
**report_attributes
|
59
|
-
)
|
46
|
+
report_template(:fail, error_slug: :missing_foreign_key)
|
60
47
|
end
|
61
48
|
end
|
49
|
+
|
50
|
+
def report_template(status, error_slug: nil)
|
51
|
+
Report.new(
|
52
|
+
status: status,
|
53
|
+
error_message: nil,
|
54
|
+
error_slug: error_slug,
|
55
|
+
primary_table: association.table_name.to_s,
|
56
|
+
primary_key: association.association_primary_key.to_s,
|
57
|
+
foreign_table: association.active_record.table_name.to_s,
|
58
|
+
foreign_key: association.foreign_key.to_s,
|
59
|
+
**report_attributes
|
60
|
+
)
|
61
|
+
end
|
62
62
|
end
|
63
63
|
end
|
64
64
|
end
|
@@ -4,21 +4,15 @@ module DatabaseConsistency
|
|
4
4
|
module Checkers
|
5
5
|
# This class checks if association's foreign key type covers associated model's primary key (same or bigger)
|
6
6
|
class ForeignKeyTypeChecker < AssociationChecker
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
@fk_name = fk_name
|
17
|
-
@fk_type = fk_type
|
18
|
-
@pk_name = pk_name
|
19
|
-
@pk_type = pk_type
|
20
|
-
end
|
21
|
-
end
|
7
|
+
Report = ReportBuilder.define(
|
8
|
+
DatabaseConsistency::Report,
|
9
|
+
:pk_name,
|
10
|
+
:pk_type,
|
11
|
+
:fk_name,
|
12
|
+
:fk_type,
|
13
|
+
:table_to_change,
|
14
|
+
:type_to_set
|
15
|
+
)
|
22
16
|
|
23
17
|
private
|
24
18
|
|
@@ -50,7 +44,7 @@ module DatabaseConsistency
|
|
50
44
|
report_template(:fail, error_slug: :inconsistent_types)
|
51
45
|
end
|
52
46
|
rescue Errors::MissingField => e
|
53
|
-
Report.new(
|
47
|
+
DatabaseConsistency::Report.new(
|
54
48
|
status: :fail,
|
55
49
|
error_slug: nil,
|
56
50
|
error_message: e.message,
|
@@ -4,15 +4,11 @@ module DatabaseConsistency
|
|
4
4
|
module Checkers
|
5
5
|
# This class checks if association's foreign key has index in the database
|
6
6
|
class MissingIndexChecker < AssociationChecker
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
@table_name = table_name
|
13
|
-
@columns = columns
|
14
|
-
end
|
15
|
-
end
|
7
|
+
Report = ReportBuilder.define(
|
8
|
+
DatabaseConsistency::Report,
|
9
|
+
:table_name,
|
10
|
+
:columns
|
11
|
+
)
|
16
12
|
|
17
13
|
private
|
18
14
|
|
@@ -4,14 +4,10 @@ module DatabaseConsistency
|
|
4
4
|
module Checkers
|
5
5
|
# This class checks missing presence validator
|
6
6
|
class NullConstraintChecker < ColumnChecker
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
super(**args)
|
12
|
-
@association_name = association_name
|
13
|
-
end
|
14
|
-
end
|
7
|
+
Report = ReportBuilder.define(
|
8
|
+
DatabaseConsistency::Report,
|
9
|
+
:association_name
|
10
|
+
)
|
15
11
|
|
16
12
|
private
|
17
13
|
|
@@ -33,22 +29,26 @@ module DatabaseConsistency
|
|
33
29
|
#
|
34
30
|
# We consider PresenceValidation, InclusionValidation, ExclusionValidation, NumericalityValidator with nil,
|
35
31
|
# or required BelongsTo association using this column
|
36
|
-
def check
|
32
|
+
def check
|
37
33
|
if valid?
|
38
34
|
report_template(:ok)
|
39
35
|
elsif belongs_to_association
|
40
|
-
|
41
|
-
status: :fail,
|
42
|
-
error_slug: :null_constraint_association_misses_validator,
|
43
|
-
error_message: nil,
|
44
|
-
association_name: belongs_to_association.name.to_s,
|
45
|
-
**report_attributes
|
46
|
-
)
|
36
|
+
report_template(:fail, error_slug: :null_constraint_association_misses_validator)
|
47
37
|
else
|
48
38
|
report_template(:fail, error_slug: :null_constraint_misses_validator)
|
49
39
|
end
|
50
40
|
end
|
51
41
|
|
42
|
+
def report_template(status, error_slug: nil)
|
43
|
+
Report.new(
|
44
|
+
status: status,
|
45
|
+
error_slug: error_slug,
|
46
|
+
error_message: nil,
|
47
|
+
association_name: belongs_to_association&.name&.to_s,
|
48
|
+
**report_attributes
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
52
|
def valid?
|
53
53
|
validator?(:presence, column.name) ||
|
54
54
|
validator?(:inclusion, column.name) ||
|
@@ -4,16 +4,12 @@ module DatabaseConsistency
|
|
4
4
|
module Checkers
|
5
5
|
# This class checks missing presence validator
|
6
6
|
class PrimaryKeyTypeChecker < ColumnChecker
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
@type_to_set = type_to_set
|
14
|
-
@fk_name = fk_name
|
15
|
-
end
|
16
|
-
end
|
7
|
+
Report = ReportBuilder.define(
|
8
|
+
DatabaseConsistency::Report,
|
9
|
+
:fk_name,
|
10
|
+
:table_to_change,
|
11
|
+
:type_to_set
|
12
|
+
)
|
17
13
|
|
18
14
|
private
|
19
15
|
|
@@ -36,22 +32,26 @@ module DatabaseConsistency
|
|
36
32
|
# | --------------------- | ------ |
|
37
33
|
# | yes | ok |
|
38
34
|
# | no | fail |
|
39
|
-
def check
|
35
|
+
def check
|
40
36
|
if valid?
|
41
37
|
report_template(:ok)
|
42
38
|
else
|
43
|
-
|
44
|
-
status: :fail,
|
45
|
-
error_slug: :small_primary_key,
|
46
|
-
error_message: nil,
|
47
|
-
table_to_change: model.table_name,
|
48
|
-
fk_name: column.name,
|
49
|
-
type_to_set: type_to_set,
|
50
|
-
**report_attributes
|
51
|
-
)
|
39
|
+
report_template(:fail, error_slug: :small_primary_key)
|
52
40
|
end
|
53
41
|
end
|
54
42
|
|
43
|
+
def report_template(status, error_slug: nil)
|
44
|
+
Report.new(
|
45
|
+
status: status,
|
46
|
+
error_slug: error_slug,
|
47
|
+
error_message: nil,
|
48
|
+
table_to_change: model.table_name,
|
49
|
+
fk_name: column.name,
|
50
|
+
type_to_set: type_to_set,
|
51
|
+
**report_attributes
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
55
|
def type_to_set
|
56
56
|
VALID_TYPES_MAP[column.sql_type.to_s] || 'bigserial'
|
57
57
|
end
|
@@ -4,15 +4,11 @@ module DatabaseConsistency
|
|
4
4
|
module Checkers
|
5
5
|
# This class checks redundant database indexes
|
6
6
|
class RedundantIndexChecker < IndexChecker
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
@covered_index_name = covered_index_name
|
13
|
-
@index_name = index_name
|
14
|
-
end
|
15
|
-
end
|
7
|
+
Report = ReportBuilder.define(
|
8
|
+
DatabaseConsistency::Report,
|
9
|
+
:covered_index_name,
|
10
|
+
:index_name
|
11
|
+
)
|
16
12
|
|
17
13
|
private
|
18
14
|
|
@@ -28,21 +24,25 @@ module DatabaseConsistency
|
|
28
24
|
# | provided | ok |
|
29
25
|
# | redundant | fail |
|
30
26
|
#
|
31
|
-
def check
|
27
|
+
def check
|
32
28
|
if covered_by_index
|
33
|
-
|
34
|
-
status: :fail,
|
35
|
-
error_slug: :redundant_index,
|
36
|
-
error_message: nil,
|
37
|
-
covered_index_name: covered_by_index.name,
|
38
|
-
index_name: index.name,
|
39
|
-
**report_attributes
|
40
|
-
)
|
29
|
+
report_template(:fail, error_slug: :redundant_index)
|
41
30
|
else
|
42
31
|
report_template(:ok)
|
43
32
|
end
|
44
33
|
end
|
45
34
|
|
35
|
+
def report_template(status, error_slug: nil)
|
36
|
+
Report.new(
|
37
|
+
status: status,
|
38
|
+
error_slug: error_slug,
|
39
|
+
error_message: nil,
|
40
|
+
covered_index_name: covered_by_index&.name,
|
41
|
+
index_name: index.name,
|
42
|
+
**report_attributes
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
46
|
def covered_by_index
|
47
47
|
@covered_by_index ||=
|
48
48
|
model.connection.indexes(model.table_name).find do |another_index|
|
@@ -4,15 +4,11 @@ module DatabaseConsistency
|
|
4
4
|
module Checkers
|
5
5
|
# This class checks redundant database indexes
|
6
6
|
class RedundantUniqueIndexChecker < IndexChecker
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
@index_name = index_name
|
13
|
-
@covered_index_name = covered_index_name
|
14
|
-
end
|
15
|
-
end
|
7
|
+
Report = ReportBuilder.define(
|
8
|
+
DatabaseConsistency::Report,
|
9
|
+
:index_name,
|
10
|
+
:covered_index_name
|
11
|
+
)
|
16
12
|
|
17
13
|
private
|
18
14
|
|
@@ -28,21 +24,25 @@ module DatabaseConsistency
|
|
28
24
|
# | provided | ok |
|
29
25
|
# | redundant | fail |
|
30
26
|
#
|
31
|
-
def check
|
27
|
+
def check
|
32
28
|
if covered_by_index
|
33
|
-
|
34
|
-
status: :fail,
|
35
|
-
error_slug: :redundant_unique_index,
|
36
|
-
error_message: nil,
|
37
|
-
index_name: index.name,
|
38
|
-
covered_index_name: covered_by_index.name,
|
39
|
-
**report_attributes
|
40
|
-
)
|
29
|
+
report_template(:fail, error_slug: :redundant_unique_index)
|
41
30
|
else
|
42
31
|
report_template(:ok)
|
43
32
|
end
|
44
33
|
end
|
45
34
|
|
35
|
+
def report_template(status, error_slug: nil)
|
36
|
+
Report.new(
|
37
|
+
status: status,
|
38
|
+
error_slug: error_slug,
|
39
|
+
error_message: nil,
|
40
|
+
index_name: index.name,
|
41
|
+
covered_index_name: covered_by_index&.name,
|
42
|
+
**report_attributes
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
46
|
def covered_by_index
|
47
47
|
@covered_by_index ||=
|
48
48
|
model.connection.indexes(model.table_name).find do |another_index|
|
@@ -4,15 +4,11 @@ module DatabaseConsistency
|
|
4
4
|
module Checkers
|
5
5
|
# This class checks if uniqueness validator has unique index in the database
|
6
6
|
class MissingUniqueIndexChecker < ValidatorChecker
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
@table_name = table_name
|
13
|
-
@columns = columns
|
14
|
-
end
|
15
|
-
end
|
7
|
+
Report = ReportBuilder.define(
|
8
|
+
DatabaseConsistency::Report,
|
9
|
+
:table_name,
|
10
|
+
:columns
|
11
|
+
)
|
16
12
|
|
17
13
|
def column_or_attribute_name
|
18
14
|
@column_or_attribute_name ||= Helper.uniqueness_validator_columns(attribute, validator, model).join('+')
|
@@ -31,21 +27,25 @@ module DatabaseConsistency
|
|
31
27
|
# | ------------ | ------ |
|
32
28
|
# | persisted | ok |
|
33
29
|
# | missing | fail |
|
34
|
-
def check
|
30
|
+
def check
|
35
31
|
if unique_index
|
36
32
|
report_template(:ok)
|
37
33
|
else
|
38
|
-
|
39
|
-
status: :fail,
|
40
|
-
error_slug: :missing_unique_index,
|
41
|
-
error_message: nil,
|
42
|
-
table_name: model.table_name,
|
43
|
-
columns: sorted_uniqueness_validator_columns,
|
44
|
-
**report_attributes
|
45
|
-
)
|
34
|
+
report_template(:fail, error_slug: :missing_unique_index)
|
46
35
|
end
|
47
36
|
end
|
48
37
|
|
38
|
+
def report_template(status, error_slug: nil)
|
39
|
+
Report.new(
|
40
|
+
status: status,
|
41
|
+
error_slug: error_slug,
|
42
|
+
error_message: nil,
|
43
|
+
table_name: model.table_name,
|
44
|
+
columns: sorted_uniqueness_validator_columns,
|
45
|
+
**report_attributes
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
49
|
def unique_index
|
50
50
|
@unique_index ||= model.connection.indexes(model.table_name).find do |index|
|
51
51
|
index.unique && Helper.extract_index_columns(index.columns).sort == sorted_uniqueness_validator_columns
|
data/lib/database_consistency/checkers/validators_fraction_checkers/column_presence_checker.rb
CHANGED
@@ -6,15 +6,11 @@ module DatabaseConsistency
|
|
6
6
|
class ColumnPresenceChecker < ValidatorsFractionChecker
|
7
7
|
WEAK_OPTIONS = %i[allow_nil allow_blank if unless on].freeze
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
@table_name = table_name
|
15
|
-
@column_name = column_name
|
16
|
-
end
|
17
|
-
end
|
9
|
+
Report = ReportBuilder.define(
|
10
|
+
DatabaseConsistency::Report,
|
11
|
+
:table_name,
|
12
|
+
:column_name
|
13
|
+
)
|
18
14
|
|
19
15
|
private
|
20
16
|
|
@@ -44,6 +40,17 @@ module DatabaseConsistency
|
|
44
40
|
report_template(:fail, error_message: e.message)
|
45
41
|
end
|
46
42
|
|
43
|
+
def report_template(status, error_message: nil, error_slug: nil)
|
44
|
+
Report.new(
|
45
|
+
status: status,
|
46
|
+
error_slug: error_slug,
|
47
|
+
error_message: error_message,
|
48
|
+
table_name: model.table_name.to_s,
|
49
|
+
column_name: attribute.to_s,
|
50
|
+
**report_attributes
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
47
54
|
def weak_option?
|
48
55
|
validators.all? { |validator| validator.options.slice(*WEAK_OPTIONS).any? }
|
49
56
|
end
|
@@ -1,16 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module DatabaseConsistency
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
@error_message = error_message
|
14
|
-
end
|
15
|
-
end
|
4
|
+
Report = ReportBuilder.define(
|
5
|
+
Class.new,
|
6
|
+
:checker_name,
|
7
|
+
:table_or_model_name,
|
8
|
+
:column_or_attribute_name,
|
9
|
+
:status,
|
10
|
+
:error_slug,
|
11
|
+
:error_message
|
12
|
+
)
|
16
13
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DatabaseConsistency
|
4
|
+
class ReportBuilder # :nodoc:
|
5
|
+
def self.define(klass, *attrs) # rubocop:disable Metrics/MethodLength
|
6
|
+
Class.new(klass) do
|
7
|
+
attr_reader(*attrs)
|
8
|
+
|
9
|
+
class_eval(<<~DEF, __FILE__, __LINE__ + 1)
|
10
|
+
def initialize(#{attrs.map { |attr| "#{attr}:" }.join(', ')}, **opts)
|
11
|
+
super(**opts) if opts.any?
|
12
|
+
#{attrs.map { |attr| "@#{attr} = #{attr}" }.join("\n")}
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_h
|
16
|
+
h = defined?(super) ? super : {}
|
17
|
+
#{attrs.map { |attr| "h[#{attr}] = #{attr}" }.join("\n")}
|
18
|
+
h
|
19
|
+
end
|
20
|
+
DEF
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DatabaseConsistency
|
4
|
+
module Writers
|
5
|
+
module Simple
|
6
|
+
class AssociationMissingIndex < Base # :nodoc:
|
7
|
+
private
|
8
|
+
|
9
|
+
def template
|
10
|
+
'associated model should have proper index in the database'
|
11
|
+
end
|
12
|
+
|
13
|
+
def unique_attributes
|
14
|
+
{
|
15
|
+
table_name: report.table_name,
|
16
|
+
columns: report.columns
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DatabaseConsistency
|
4
|
+
module Writers
|
5
|
+
module Simple
|
6
|
+
class AssociationMissingNullConstraint < Base # :nodoc:
|
7
|
+
private
|
8
|
+
|
9
|
+
def template
|
10
|
+
'association foreign key column should be required in the database'
|
11
|
+
end
|
12
|
+
|
13
|
+
def unique_attributes
|
14
|
+
{
|
15
|
+
table_name: report.table_name,
|
16
|
+
column_name: report.column_name
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -33,11 +33,19 @@ module DatabaseConsistency
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def msg
|
36
|
-
"#{report.checker_name} #{status_text} #{key_text} #{message_text}"
|
36
|
+
"#{report.checker_name} #{status_text} #{key_text} #{message_text}".strip
|
37
|
+
end
|
38
|
+
|
39
|
+
def unique_key
|
40
|
+
{ class: self.class }.merge(unique_attributes)
|
37
41
|
end
|
38
42
|
|
39
43
|
private
|
40
44
|
|
45
|
+
def unique_attributes
|
46
|
+
raise StandardError, 'Missing the implementation'
|
47
|
+
end
|
48
|
+
|
41
49
|
def message_text
|
42
50
|
template % attributes
|
43
51
|
end
|
@@ -3,12 +3,16 @@
|
|
3
3
|
module DatabaseConsistency
|
4
4
|
module Writers
|
5
5
|
module Simple
|
6
|
-
class
|
6
|
+
class DefaultMessage < Base # :nodoc:
|
7
7
|
private
|
8
8
|
|
9
9
|
def template
|
10
10
|
report.error_message || ''
|
11
11
|
end
|
12
|
+
|
13
|
+
def unique_attributes
|
14
|
+
report.to_h
|
15
|
+
end
|
12
16
|
end
|
13
17
|
end
|
14
18
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DatabaseConsistency
|
4
|
+
module Writers
|
5
|
+
module Simple
|
6
|
+
class HasOneMissingUniqueIndex < Base # :nodoc:
|
7
|
+
private
|
8
|
+
|
9
|
+
def template
|
10
|
+
'associated model should have proper unique index in the database'
|
11
|
+
end
|
12
|
+
|
13
|
+
def unique_attributes
|
14
|
+
{
|
15
|
+
table_name: report.table_name,
|
16
|
+
columns: report.columns,
|
17
|
+
unique: true
|
18
|
+
}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -7,7 +7,8 @@ module DatabaseConsistency
|
|
7
7
|
private
|
8
8
|
|
9
9
|
def template
|
10
|
-
"foreign key %<fk_name>s with type %<fk_type>s doesn't
|
10
|
+
"foreign key (%<fk_name>s) with type (%<fk_type>s) doesn't "\
|
11
|
+
'cover primary key (%<pk_name>s) with type (%<pk_type>s)'
|
11
12
|
end
|
12
13
|
|
13
14
|
def attributes
|
@@ -18,6 +19,14 @@ module DatabaseConsistency
|
|
18
19
|
pk_type: report.pk_type
|
19
20
|
}
|
20
21
|
end
|
22
|
+
|
23
|
+
def unique_attributes
|
24
|
+
{
|
25
|
+
table_to_change: report.table_to_change,
|
26
|
+
type_to_set: report.type_to_set,
|
27
|
+
fk_name: report.fk_name
|
28
|
+
}
|
29
|
+
end
|
21
30
|
end
|
22
31
|
end
|
23
32
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DatabaseConsistency
|
4
|
+
module Writers
|
5
|
+
module Simple
|
6
|
+
class LengthValidatorGreaterLimit < Base # :nodoc:
|
7
|
+
private
|
8
|
+
|
9
|
+
def template
|
10
|
+
'column has greater limit in the database than in length validator'
|
11
|
+
end
|
12
|
+
|
13
|
+
def unique_attributes
|
14
|
+
{
|
15
|
+
table_or_model_name: report.table_or_model_name,
|
16
|
+
column_or_attribute_name: report.column_or_attribute_name
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DatabaseConsistency
|
4
|
+
module Writers
|
5
|
+
module Simple
|
6
|
+
class LengthValidatorLowerLimit < Base # :nodoc:
|
7
|
+
private
|
8
|
+
|
9
|
+
def template
|
10
|
+
'column has lower limit in the database than in length validator'
|
11
|
+
end
|
12
|
+
|
13
|
+
def unique_attributes
|
14
|
+
{
|
15
|
+
table_or_model_name: report.table_or_model_name,
|
16
|
+
column_or_attribute_name: report.column_or_attribute_name
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DatabaseConsistency
|
4
|
+
module Writers
|
5
|
+
module Simple
|
6
|
+
class LengthValidatorMissing < Base # :nodoc:
|
7
|
+
private
|
8
|
+
|
9
|
+
def template
|
10
|
+
'column has limit in the database but do not have length validator'
|
11
|
+
end
|
12
|
+
|
13
|
+
def unique_attributes
|
14
|
+
{
|
15
|
+
table_or_model_name: report.table_or_model_name,
|
16
|
+
column_or_attribute_name: report.column_or_attribute_name
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DatabaseConsistency
|
4
|
+
module Writers
|
5
|
+
module Simple
|
6
|
+
class MissingForeignKey < Base # :nodoc:
|
7
|
+
private
|
8
|
+
|
9
|
+
def template
|
10
|
+
'should have foreign key in the database'
|
11
|
+
end
|
12
|
+
|
13
|
+
def unique_attributes
|
14
|
+
{
|
15
|
+
foreign_table: report.foreign_table,
|
16
|
+
foreign_key: report.foreign_key,
|
17
|
+
primary_table: report.primary_table,
|
18
|
+
primary_key: report.primary_key
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DatabaseConsistency
|
4
|
+
module Writers
|
5
|
+
module Simple
|
6
|
+
class MissingUniqueIndex < Base # :nodoc:
|
7
|
+
private
|
8
|
+
|
9
|
+
def template
|
10
|
+
'model should have proper unique index in the database'
|
11
|
+
end
|
12
|
+
|
13
|
+
def unique_attributes
|
14
|
+
{
|
15
|
+
table_name: report.table_name,
|
16
|
+
columns: report.columns,
|
17
|
+
unique: true
|
18
|
+
}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DatabaseConsistency
|
4
|
+
module Writers
|
5
|
+
module Simple
|
6
|
+
class MissingUniquenessValidation < Base # :nodoc:
|
7
|
+
private
|
8
|
+
|
9
|
+
def template
|
10
|
+
'index is unique in the database but do not have uniqueness validator'
|
11
|
+
end
|
12
|
+
|
13
|
+
def unique_attributes
|
14
|
+
{
|
15
|
+
table_or_model_name: report.table_or_model_name,
|
16
|
+
column_or_attribute_name: report.column_or_attribute_name
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/database_consistency/writers/simple/null_constraint_association_misses_validator.rb
CHANGED
@@ -15,6 +15,13 @@ module DatabaseConsistency
|
|
15
15
|
association_name: report.association_name
|
16
16
|
}
|
17
17
|
end
|
18
|
+
|
19
|
+
def unique_attributes
|
20
|
+
{
|
21
|
+
table_or_model_name: report.table_or_model_name,
|
22
|
+
column_or_attribute_name: report.column_or_attribute_name
|
23
|
+
}
|
24
|
+
end
|
18
25
|
end
|
19
26
|
end
|
20
27
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DatabaseConsistency
|
4
|
+
module Writers
|
5
|
+
module Simple
|
6
|
+
class NullConstraintMissesValidator < Base # :nodoc:
|
7
|
+
private
|
8
|
+
|
9
|
+
def template
|
10
|
+
'column is required in the database but do not have presence validator'
|
11
|
+
end
|
12
|
+
|
13
|
+
def unique_attributes
|
14
|
+
{
|
15
|
+
table_or_model_name: report.table_or_model_name,
|
16
|
+
column_or_attribute_name: report.column_or_attribute_name
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DatabaseConsistency
|
4
|
+
module Writers
|
5
|
+
module Simple
|
6
|
+
class NullConstraintMissing < Base # :nodoc:
|
7
|
+
private
|
8
|
+
|
9
|
+
def template
|
10
|
+
'column should be required in the database'
|
11
|
+
end
|
12
|
+
|
13
|
+
def unique_attributes
|
14
|
+
{
|
15
|
+
table_name: report.table_name,
|
16
|
+
column_name: report.column_name
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DatabaseConsistency
|
4
|
+
module Writers
|
5
|
+
module Simple
|
6
|
+
class PossibleNull < Base # :nodoc:
|
7
|
+
private
|
8
|
+
|
9
|
+
def template
|
10
|
+
'column is required but there is possible null value insert'
|
11
|
+
end
|
12
|
+
|
13
|
+
def unique_attributes
|
14
|
+
{
|
15
|
+
table_or_model_name: report.table_or_model_name,
|
16
|
+
column_or_attribute_name: report.column_or_attribute_name
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DatabaseConsistency
|
4
|
+
module Writers
|
5
|
+
module Simple
|
6
|
+
class SmallPrimaryKey < Base # :nodoc:
|
7
|
+
private
|
8
|
+
|
9
|
+
def template
|
10
|
+
'column has int/serial type but recommended to have bigint/bigserial/uuid'
|
11
|
+
end
|
12
|
+
|
13
|
+
def unique_attributes
|
14
|
+
{
|
15
|
+
table_or_model_name: report.table_or_model_name,
|
16
|
+
column_or_attribute_name: report.column_or_attribute_name
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -6,43 +6,49 @@ module DatabaseConsistency
|
|
6
6
|
# The simplest formatter
|
7
7
|
class SimpleWriter < BaseWriter
|
8
8
|
SLUG_TO_WRITER = {
|
9
|
-
association_missing_index: Simple::
|
10
|
-
association_missing_null_constraint: Simple::
|
11
|
-
has_one_missing_unique_index: Simple::
|
9
|
+
association_missing_index: Simple::AssociationMissingIndex,
|
10
|
+
association_missing_null_constraint: Simple::AssociationMissingNullConstraint,
|
11
|
+
has_one_missing_unique_index: Simple::HasOneMissingUniqueIndex,
|
12
12
|
inconsistent_types: Simple::InconsistentTypes,
|
13
|
-
length_validator_greater_limit: Simple::
|
14
|
-
length_validator_lower_limit: Simple::
|
15
|
-
length_validator_missing: Simple::
|
16
|
-
missing_foreign_key: Simple::
|
17
|
-
missing_unique_index: Simple::
|
18
|
-
missing_uniqueness_validation: Simple::
|
13
|
+
length_validator_greater_limit: Simple::LengthValidatorGreaterLimit,
|
14
|
+
length_validator_lower_limit: Simple::LengthValidatorLowerLimit,
|
15
|
+
length_validator_missing: Simple::LengthValidatorMissing,
|
16
|
+
missing_foreign_key: Simple::MissingForeignKey,
|
17
|
+
missing_unique_index: Simple::MissingUniqueIndex,
|
18
|
+
missing_uniqueness_validation: Simple::MissingUniquenessValidation,
|
19
19
|
null_constraint_association_misses_validator: Simple::NullConstraintAssociationMissesValidator,
|
20
|
-
null_constraint_misses_validator: Simple::
|
21
|
-
null_constraint_missing: Simple::
|
22
|
-
possible_null: Simple::
|
20
|
+
null_constraint_misses_validator: Simple::NullConstraintMissesValidator,
|
21
|
+
null_constraint_missing: Simple::NullConstraintMissing,
|
22
|
+
possible_null: Simple::PossibleNull,
|
23
23
|
redundant_index: Simple::RedundantIndex,
|
24
24
|
redundant_unique_index: Simple::RedundantUniqueIndex,
|
25
|
-
small_primary_key: Simple::
|
25
|
+
small_primary_key: Simple::SmallPrimaryKey
|
26
26
|
}.freeze
|
27
27
|
|
28
28
|
def write
|
29
|
-
results.
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
puts writer.msg
|
29
|
+
results.select(&method(:write?))
|
30
|
+
.map(&method(:writer))
|
31
|
+
.group_by(&:unique_key)
|
32
|
+
.each_value do |writers|
|
33
|
+
puts message(writers)
|
35
34
|
end
|
36
35
|
end
|
37
36
|
|
38
37
|
private
|
39
38
|
|
40
|
-
def
|
41
|
-
|
39
|
+
def message(writers)
|
40
|
+
msg = writers.first.msg
|
41
|
+
return msg if writers.size == 1
|
42
|
+
|
43
|
+
"#{msg}. Total grouped offenses: #{writers.size}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def write?(report)
|
47
|
+
report.status == :fail || config.debug?
|
42
48
|
end
|
43
49
|
|
44
50
|
def writer(report)
|
45
|
-
klass = SLUG_TO_WRITER[report.error_slug] || Simple::
|
51
|
+
klass = SLUG_TO_WRITER[report.error_slug] || Simple::DefaultMessage
|
46
52
|
klass.new(report, config: config)
|
47
53
|
end
|
48
54
|
end
|
data/lib/database_consistency.rb
CHANGED
@@ -7,17 +7,31 @@ require 'database_consistency/helper'
|
|
7
7
|
require 'database_consistency/configuration'
|
8
8
|
require 'database_consistency/rescue_error'
|
9
9
|
require 'database_consistency/errors'
|
10
|
+
require 'database_consistency/report_builder'
|
10
11
|
require 'database_consistency/report'
|
11
12
|
|
12
13
|
require 'database_consistency/writers/base_writer'
|
13
14
|
require 'database_consistency/writers/todo_writer'
|
14
15
|
|
15
16
|
require 'database_consistency/writers/simple/base'
|
16
|
-
require 'database_consistency/writers/simple/
|
17
|
+
require 'database_consistency/writers/simple/default_message'
|
17
18
|
require 'database_consistency/writers/simple/inconsistent_types'
|
18
19
|
require 'database_consistency/writers/simple/null_constraint_association_misses_validator'
|
19
20
|
require 'database_consistency/writers/simple/redundant_index'
|
20
21
|
require 'database_consistency/writers/simple/redundant_unique_index'
|
22
|
+
require 'database_consistency/writers/simple/association_missing_index'
|
23
|
+
require 'database_consistency/writers/simple/association_missing_null_constraint'
|
24
|
+
require 'database_consistency/writers/simple/has_one_missing_unique_index'
|
25
|
+
require 'database_consistency/writers/simple/length_validator_lower_limit'
|
26
|
+
require 'database_consistency/writers/simple/length_validator_greater_limit'
|
27
|
+
require 'database_consistency/writers/simple/length_validator_missing'
|
28
|
+
require 'database_consistency/writers/simple/missing_foreign_key'
|
29
|
+
require 'database_consistency/writers/simple/missing_unique_index'
|
30
|
+
require 'database_consistency/writers/simple/missing_uniqueness_validation'
|
31
|
+
require 'database_consistency/writers/simple/null_constraint_misses_validator'
|
32
|
+
require 'database_consistency/writers/simple/null_constraint_missing'
|
33
|
+
require 'database_consistency/writers/simple/possible_null'
|
34
|
+
require 'database_consistency/writers/simple/small_primary_key'
|
21
35
|
require 'database_consistency/writers/simple_writer'
|
22
36
|
|
23
37
|
require 'database_consistency/writers/autofix/helpers/migration'
|
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.3.
|
4
|
+
version: 1.3.7
|
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-11-
|
11
|
+
date: 2022-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -176,6 +176,7 @@ files:
|
|
176
176
|
- lib/database_consistency/processors/validators_fractions_processor.rb
|
177
177
|
- lib/database_consistency/processors/validators_processor.rb
|
178
178
|
- lib/database_consistency/report.rb
|
179
|
+
- lib/database_consistency/report_builder.rb
|
179
180
|
- lib/database_consistency/rescue_error.rb
|
180
181
|
- lib/database_consistency/templates/rails_defaults.yml
|
181
182
|
- lib/database_consistency/version.rb
|
@@ -196,12 +197,25 @@ files:
|
|
196
197
|
- lib/database_consistency/writers/autofix/templates/redundant_index.tt
|
197
198
|
- lib/database_consistency/writers/autofix_writer.rb
|
198
199
|
- lib/database_consistency/writers/base_writer.rb
|
200
|
+
- lib/database_consistency/writers/simple/association_missing_index.rb
|
201
|
+
- lib/database_consistency/writers/simple/association_missing_null_constraint.rb
|
199
202
|
- lib/database_consistency/writers/simple/base.rb
|
200
|
-
- lib/database_consistency/writers/simple/
|
203
|
+
- lib/database_consistency/writers/simple/default_message.rb
|
204
|
+
- lib/database_consistency/writers/simple/has_one_missing_unique_index.rb
|
201
205
|
- lib/database_consistency/writers/simple/inconsistent_types.rb
|
206
|
+
- lib/database_consistency/writers/simple/length_validator_greater_limit.rb
|
207
|
+
- lib/database_consistency/writers/simple/length_validator_lower_limit.rb
|
208
|
+
- lib/database_consistency/writers/simple/length_validator_missing.rb
|
209
|
+
- lib/database_consistency/writers/simple/missing_foreign_key.rb
|
210
|
+
- lib/database_consistency/writers/simple/missing_unique_index.rb
|
211
|
+
- lib/database_consistency/writers/simple/missing_uniqueness_validation.rb
|
202
212
|
- lib/database_consistency/writers/simple/null_constraint_association_misses_validator.rb
|
213
|
+
- lib/database_consistency/writers/simple/null_constraint_misses_validator.rb
|
214
|
+
- lib/database_consistency/writers/simple/null_constraint_missing.rb
|
215
|
+
- lib/database_consistency/writers/simple/possible_null.rb
|
203
216
|
- lib/database_consistency/writers/simple/redundant_index.rb
|
204
217
|
- lib/database_consistency/writers/simple/redundant_unique_index.rb
|
218
|
+
- lib/database_consistency/writers/simple/small_primary_key.rb
|
205
219
|
- lib/database_consistency/writers/simple_writer.rb
|
206
220
|
- lib/database_consistency/writers/todo_writer.rb
|
207
221
|
homepage: https://github.com/djezzzl/database_consistency
|