database_consistency 3.0.6 → 3.0.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 41244c7508ff0579de421a22e770767de915176ef2e43ed9371daadf6cdd9243
4
- data.tar.gz: bb38bf3073e135b1e6c039a451237a5bcd71a4c03484e4926ddc00cc41faa7b3
3
+ metadata.gz: d1a3f79e718dbab025a1077436d34a99f96441d4c38ea6eeab44b48a9d47017b
4
+ data.tar.gz: 3d923752051575203683bf72e4fa91d538e668d0f3259be1a3c85f078bd35fc8
5
5
  SHA512:
6
- metadata.gz: 5b26db588fda6d08012fd845ad04141d6a03bb26c058c6cf9042c344c6a6cf6304c98efc89d9ae89c0ee58d8eb4a918e2d1a725578aa60782df036b665f2d638
7
- data.tar.gz: c1b6d1abd2eab007e48ad83e157feaee26ea2b2485c243c8bde0e44685f862b01386d9ef5295693883ae3decc85274f27c6a33b9392c799108ee80e8f0bd5f1b
6
+ metadata.gz: 483695e3e1bfb73d833f71832f770e6783bab926c785bb54e097a0f527adc66a33112e7c83f3e7f1f849d5f0015d8f16e01bcff135d55933c683f76dbb58626d
7
+ data.tar.gz: f0686a44bb3fe3e842ad8b9f72a4b11801cad4745c389665d015bc0255529709b4b4f843d4a97a5064e5ede8643c3f5d36b800c2c4f63ad7b0f4bf6119544f4b
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Checkers
5
+ # This class checks if numericality validator has check constraint in the database
6
+ class NumericalityConstraintChecker < ValidatorsFractionChecker
7
+ SQL_KEYWORDS = %w[
8
+ and or not null is true false in like between case when then else end check
9
+ exists select where having order group limit offset distinct all any some
10
+ from join on using as by union into values set update delete insert with
11
+ ].freeze
12
+ PLAIN_IDENTIFIER_PATTERN =
13
+ /\b([a-zA-Z_][a-zA-Z0-9_]*(?:\.[a-zA-Z_][a-zA-Z0-9_]*)?)\b(?!\s*\()/.freeze
14
+
15
+ private
16
+
17
+ def filter(validator)
18
+ validator.kind == :numericality
19
+ end
20
+
21
+ def preconditions
22
+ model.connection.respond_to?(:check_constraints) &&
23
+ model.connection.table_exists?(model.table_name) &&
24
+ column &&
25
+ validators.any?
26
+ end
27
+
28
+ def check
29
+ if check_constraint_for_column?
30
+ report_template(:ok)
31
+ else
32
+ report_template(:fail, error_slug: :numericality_check_constraint_missing)
33
+ end
34
+ end
35
+
36
+ def check_constraint_for_column?
37
+ check_constraints.any? do |constraint|
38
+ constraint_columns(constraint.expression).include?(column.name.downcase)
39
+ end
40
+ end
41
+
42
+ def check_constraints
43
+ @check_constraints ||= model.connection.check_constraints(model.table_name)
44
+ rescue StandardError
45
+ []
46
+ end
47
+
48
+ def constraint_columns(expression)
49
+ expression_sql = expression.to_s
50
+ # Captures identifiers in three forms:
51
+ # 1) "double quoted", 2) `backtick quoted`, 3) plain SQL identifiers.
52
+ # Plain identifiers followed by `(` are excluded to skip SQL function names.
53
+ quoted_identifiers = expression_sql.scan(/"([^"]+)"|`([^`]+)`/).flatten.compact
54
+ # Only the column part is needed for comparison, so `table.column` is
55
+ # reduced to `column`.
56
+ # `(?!\s*\()` excludes function names such as `ABS(`.
57
+ plain_identifiers = expression_sql.scan(PLAIN_IDENTIFIER_PATTERN)
58
+ .flatten
59
+ .map { |identifier| identifier.split('.').last }
60
+
61
+ (quoted_identifiers + plain_identifiers).map(&:downcase).reject do |identifier|
62
+ SQL_KEYWORDS.include?(identifier)
63
+ end
64
+ end
65
+
66
+ def column
67
+ @column ||= model.columns.find { |field| field.name == attribute.to_s }
68
+ end
69
+ end
70
+ end
71
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DatabaseConsistency
4
- VERSION = '3.0.6'
4
+ VERSION = '3.0.8'
5
5
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatabaseConsistency
4
+ module Writers
5
+ module Simple
6
+ class NumericalityCheckConstraintMissing < Base # :nodoc:
7
+ private
8
+
9
+ def template
10
+ 'column has a numericality validator but does not have a CHECK constraint'
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
@@ -36,6 +36,7 @@ require 'database_consistency/writers/simple/missing_uniqueness_validation'
36
36
  require 'database_consistency/writers/simple/null_constraint_misses_validator'
37
37
  require 'database_consistency/writers/simple/null_constraint_missing'
38
38
  require 'database_consistency/writers/simple/possible_null'
39
+ require 'database_consistency/writers/simple/numericality_check_constraint_missing'
39
40
  require 'database_consistency/writers/simple/small_primary_key'
40
41
  require 'database_consistency/writers/simple/inconsistent_enum_type'
41
42
  require 'database_consistency/writers/simple/enum_values_inconsistent_with_ar_enum'
@@ -109,6 +110,7 @@ require 'database_consistency/checkers/validator_checkers/case_sensitive_unique_
109
110
 
110
111
  require 'database_consistency/checkers/validators_fraction_checkers/validators_fraction_checker'
111
112
  require 'database_consistency/checkers/validators_fraction_checkers/column_presence_checker'
113
+ require 'database_consistency/checkers/validators_fraction_checkers/numericality_constraint_checker'
112
114
 
113
115
  require 'database_consistency/checkers/index_checkers/index_checker'
114
116
  require 'database_consistency/checkers/index_checkers/unique_index_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: 3.0.6
4
+ version: 3.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evgeniy Demin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-07-19 00:00:00.000000000 Z
11
+ date: 2026-07-28 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/checkers/validator_checkers/missing_unique_index_checker.rb
177
177
  - lib/database_consistency/checkers/validator_checkers/validator_checker.rb
178
178
  - lib/database_consistency/checkers/validators_fraction_checkers/column_presence_checker.rb
179
+ - lib/database_consistency/checkers/validators_fraction_checkers/numericality_constraint_checker.rb
179
180
  - lib/database_consistency/checkers/validators_fraction_checkers/validators_fraction_checker.rb
180
181
  - lib/database_consistency/configuration.rb
181
182
  - lib/database_consistency/databases/factory.rb
@@ -241,6 +242,7 @@ files:
241
242
  - lib/database_consistency/writers/simple/null_constraint_association_misses_validator.rb
242
243
  - lib/database_consistency/writers/simple/null_constraint_misses_validator.rb
243
244
  - lib/database_consistency/writers/simple/null_constraint_missing.rb
245
+ - lib/database_consistency/writers/simple/numericality_check_constraint_missing.rb
244
246
  - lib/database_consistency/writers/simple/polymorphic_association_nullability_mismatch.rb
245
247
  - lib/database_consistency/writers/simple/possible_null.rb
246
248
  - lib/database_consistency/writers/simple/redundant_case_insensitive_option.rb