database_consistency 0.1.0 → 0.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 +4 -4
- data/lib/database_consistency/column_verifiers/base_verifier.rb +23 -0
- data/lib/database_consistency/column_verifiers/presence_missing_verifier.rb +26 -0
- data/lib/database_consistency/comparators/base_comparator.rb +3 -5
- data/lib/database_consistency/comparators/presence_comparator.rb +12 -5
- data/lib/database_consistency/database_processor.rb +18 -0
- data/lib/database_consistency/helper.rb +7 -0
- data/lib/database_consistency/report.rb +17 -0
- data/lib/database_consistency/{processor.rb → validators_processor.rb} +7 -7
- data/lib/database_consistency/version.rb +1 -1
- data/lib/database_consistency/writers/base_writer.rb +5 -1
- data/lib/database_consistency/writers/simple_writer.rb +12 -10
- data/lib/database_consistency.rb +15 -4
- metadata +7 -4
- data/lib/database_consistency/comparison.rb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c50d282f04ae0e4003a596551369213ea66ee986a6f2486a3761ec36af6d87b3
|
4
|
+
data.tar.gz: 14141f85bb9ced24c2cf4fe69d2ace3a0aa0218e4f181846d2c0dfcf88569d9d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 90577c3faf083a0c694ac8d1146d5980e7ff69df6be7578cb57069bf62a4bc3455c2f8b4a639ccae2b75f8db8473c3c5e1733e407ca0e3292a5610062e48313b
|
7
|
+
data.tar.gz: 1d638396701af3be6591db67d5782cae92d4af14fb38a4a076834836b2b7988772ee053056247d56984f2830185dd9b7703464efabec21d99e8674b112b0abfa
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module DatabaseConsistency
|
2
|
+
module ColumnVerifiers
|
3
|
+
# The base class for column verifiers
|
4
|
+
class BaseVerifier
|
5
|
+
attr_reader :model, :column
|
6
|
+
|
7
|
+
delegate :result, to: :report
|
8
|
+
|
9
|
+
def initialize(model, column)
|
10
|
+
@model = model
|
11
|
+
@column = column
|
12
|
+
end
|
13
|
+
|
14
|
+
def report
|
15
|
+
Report.new(column: column)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.verify(model, column)
|
19
|
+
new(model, column).verify
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module DatabaseConsistency
|
2
|
+
module ColumnVerifiers
|
3
|
+
# This class verifies that column needs a presence validator
|
4
|
+
class PresenceMissingVerifier < BaseVerifier
|
5
|
+
VALIDATOR_MISSING = 'is required but do not have presence validator'.freeze
|
6
|
+
|
7
|
+
def verify
|
8
|
+
result(:fail, Helper.message(column, VALIDATOR_MISSING)) unless skip? || validator?
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def skip?
|
14
|
+
column.null ||
|
15
|
+
column.name == model.primary_key ||
|
16
|
+
(model.record_timestamps? && %w[created_at updated_at].include?(column.name))
|
17
|
+
end
|
18
|
+
|
19
|
+
def validator?
|
20
|
+
model.validators.grep(ActiveModel::Validations::PresenceValidator).any? do |validator|
|
21
|
+
validator.attributes.include?(column.name) || validator.attributes.include?(column.name.to_sym)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -4,17 +4,15 @@ module DatabaseConsistency
|
|
4
4
|
class BaseComparator
|
5
5
|
attr_reader :validator, :column
|
6
6
|
|
7
|
-
delegate :result, to: :
|
8
|
-
|
9
|
-
private_class_method :new
|
7
|
+
delegate :result, to: :report
|
10
8
|
|
11
9
|
def initialize(validator, column)
|
12
10
|
@validator = validator
|
13
11
|
@column = column
|
14
12
|
end
|
15
13
|
|
16
|
-
def
|
17
|
-
|
14
|
+
def report
|
15
|
+
Report.new(validator: validator, column: column)
|
18
16
|
end
|
19
17
|
|
20
18
|
def self.compare(validator, column)
|
@@ -3,8 +3,9 @@ module DatabaseConsistency
|
|
3
3
|
# The comparator class for {{ActiveModel::Validations::PresenceValidator}}
|
4
4
|
class PresenceComparator < BaseComparator
|
5
5
|
WEAK_OPTIONS = %i[allow_nil allow_blank if unless].freeze
|
6
|
-
|
7
|
-
|
6
|
+
# Message templates
|
7
|
+
CONSTRAINT_MISSING = 'should be required in the database'.freeze
|
8
|
+
POSSIBLE_NULL = 'is required but possible null value insert'.freeze
|
8
9
|
|
9
10
|
# Table of possible statuses
|
10
11
|
# | allow_nil/allow_blank/if/unless | database | status |
|
@@ -18,13 +19,19 @@ module DatabaseConsistency
|
|
18
19
|
has_weak_option = validator.options.slice(*WEAK_OPTIONS).any?
|
19
20
|
|
20
21
|
if can_be_null == has_weak_option
|
21
|
-
result(:ok)
|
22
|
+
result(:ok, message)
|
22
23
|
elsif can_be_null
|
23
|
-
result(:fail, CONSTRAINT_MISSING)
|
24
|
+
result(:fail, message(CONSTRAINT_MISSING))
|
24
25
|
else
|
25
|
-
result(:fail, POSSIBLE_NULL)
|
26
|
+
result(:fail, message(POSSIBLE_NULL))
|
26
27
|
end
|
27
28
|
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def message(template = nil)
|
33
|
+
Helper.message(column, template)
|
34
|
+
end
|
28
35
|
end
|
29
36
|
end
|
30
37
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module DatabaseConsistency
|
2
|
+
# The class to process missing validators
|
3
|
+
class DatabaseProcessor
|
4
|
+
VERIFIERS = [
|
5
|
+
ColumnVerifiers::PresenceMissingVerifier
|
6
|
+
].freeze
|
7
|
+
|
8
|
+
def reports
|
9
|
+
Helper.models.flat_map do |model|
|
10
|
+
model.columns.flat_map do |column|
|
11
|
+
VERIFIERS.map do |verifier|
|
12
|
+
verifier.verify(model, column)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end.compact
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -17,5 +17,12 @@ module DatabaseConsistency
|
|
17
17
|
def find_field(model, attribute)
|
18
18
|
model.columns.select.find { |field| field.name == attribute }
|
19
19
|
end
|
20
|
+
|
21
|
+
# @return [String]
|
22
|
+
def message(column, template = nil)
|
23
|
+
str = "column #{column.name} of table #{column.table_name}"
|
24
|
+
str += " #{template}" if template
|
25
|
+
str
|
26
|
+
end
|
20
27
|
end
|
21
28
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module DatabaseConsistency
|
2
|
+
# This class outputs the report result
|
3
|
+
class Report
|
4
|
+
attr_reader :opts
|
5
|
+
|
6
|
+
def initialize(opts = {})
|
7
|
+
@opts = opts
|
8
|
+
end
|
9
|
+
|
10
|
+
def result(status, message)
|
11
|
+
{
|
12
|
+
status: status,
|
13
|
+
message: message
|
14
|
+
}.tap { |hash| hash[:opts] = opts unless opts.empty? }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
module DatabaseConsistency
|
2
|
-
# The class to
|
3
|
-
class
|
2
|
+
# The class to process all comparators
|
3
|
+
class ValidatorsProcessor
|
4
4
|
COMPARATORS = {
|
5
5
|
presence: DatabaseConsistency::Comparators::PresenceComparator
|
6
6
|
}.freeze
|
7
7
|
|
8
|
-
def
|
9
|
-
Helper.models.
|
10
|
-
|
8
|
+
def reports
|
9
|
+
Helper.models.flat_map do |model|
|
10
|
+
model.validators.flat_map do |validator|
|
11
11
|
next unless (comparator = COMPARATORS[validator.kind])
|
12
12
|
|
13
13
|
validator.attributes.map do |attribute|
|
@@ -15,8 +15,8 @@ module DatabaseConsistency
|
|
15
15
|
|
16
16
|
comparator.compare(validator, column)
|
17
17
|
end
|
18
|
-
end
|
19
|
-
end
|
18
|
+
end
|
19
|
+
end.compact
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -8,18 +8,20 @@ module DatabaseConsistency
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def format
|
11
|
-
results.map do |
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end.tap(&:compact!).map(&:lstrip).join("\n")
|
16
|
-
end.join("\n")
|
11
|
+
results.map do |result|
|
12
|
+
next unless write?(result[:status])
|
13
|
+
line(result)
|
14
|
+
end.tap(&:compact!).map(&:lstrip).delete_if(&:empty?).join(delimiter)
|
17
15
|
end
|
18
16
|
|
19
|
-
def
|
20
|
-
|
21
|
-
|
22
|
-
|
17
|
+
def delimiter
|
18
|
+
debug? ? "\n\n" : "\n"
|
19
|
+
end
|
20
|
+
|
21
|
+
def line(result)
|
22
|
+
"#{result[:status]} #{result[:message]}".tap do |str|
|
23
|
+
str.concat " #{result[:opts].inspect}" if debug?
|
24
|
+
end
|
23
25
|
end
|
24
26
|
end
|
25
27
|
end
|
data/lib/database_consistency.rb
CHANGED
@@ -1,21 +1,32 @@
|
|
1
1
|
require 'active_record'
|
2
2
|
|
3
3
|
require 'database_consistency/version'
|
4
|
+
require 'database_consistency/report'
|
5
|
+
require 'database_consistency/helper'
|
6
|
+
|
4
7
|
require 'database_consistency/writers/base_writer'
|
5
8
|
require 'database_consistency/writers/simple_writer'
|
6
|
-
|
7
|
-
require 'database_consistency/helper'
|
9
|
+
|
8
10
|
require 'database_consistency/comparators/base_comparator'
|
9
11
|
require 'database_consistency/comparators/presence_comparator'
|
10
|
-
require 'database_consistency/
|
12
|
+
require 'database_consistency/validators_processor'
|
13
|
+
|
14
|
+
require 'database_consistency/column_verifiers/base_verifier'
|
15
|
+
require 'database_consistency/column_verifiers/presence_missing_verifier'
|
16
|
+
require 'database_consistency/database_processor'
|
11
17
|
|
12
18
|
# The root module
|
13
19
|
module DatabaseConsistency
|
14
20
|
def self.run
|
15
21
|
Helper.load_environment!
|
16
22
|
|
23
|
+
reports = [
|
24
|
+
ValidatorsProcessor.new,
|
25
|
+
DatabaseProcessor.new
|
26
|
+
].flat_map(&:reports)
|
27
|
+
|
17
28
|
Writers::SimpleWriter.write(
|
18
|
-
|
29
|
+
reports,
|
19
30
|
ENV['LOG_LEVEL'] || 'INFO'
|
20
31
|
)
|
21
32
|
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.
|
4
|
+
version: 0.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: 2018-10-
|
11
|
+
date: 2018-10-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -110,11 +110,14 @@ extra_rdoc_files: []
|
|
110
110
|
files:
|
111
111
|
- bin/database_consistency
|
112
112
|
- lib/database_consistency.rb
|
113
|
+
- lib/database_consistency/column_verifiers/base_verifier.rb
|
114
|
+
- lib/database_consistency/column_verifiers/presence_missing_verifier.rb
|
113
115
|
- lib/database_consistency/comparators/base_comparator.rb
|
114
116
|
- lib/database_consistency/comparators/presence_comparator.rb
|
115
|
-
- lib/database_consistency/
|
117
|
+
- lib/database_consistency/database_processor.rb
|
116
118
|
- lib/database_consistency/helper.rb
|
117
|
-
- lib/database_consistency/
|
119
|
+
- lib/database_consistency/report.rb
|
120
|
+
- lib/database_consistency/validators_processor.rb
|
118
121
|
- lib/database_consistency/version.rb
|
119
122
|
- lib/database_consistency/writers/base_writer.rb
|
120
123
|
- lib/database_consistency/writers/simple_writer.rb
|
@@ -1,25 +0,0 @@
|
|
1
|
-
module DatabaseConsistency
|
2
|
-
# This class outputs the comparison result
|
3
|
-
class Comparison
|
4
|
-
attr_reader :validator, :column
|
5
|
-
|
6
|
-
private_class_method :new
|
7
|
-
|
8
|
-
def initialize(validator, column)
|
9
|
-
@validator = validator
|
10
|
-
@column = column
|
11
|
-
end
|
12
|
-
|
13
|
-
def result(status, message = nil)
|
14
|
-
{
|
15
|
-
column: column,
|
16
|
-
validator: validator,
|
17
|
-
status: status
|
18
|
-
}.tap { |hash| hash[:message] = message if message }
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.for(validator, column)
|
22
|
-
new(validator, column)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|