generated_schema_validations 0.4.0 → 0.5.1
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/README.md +15 -0
- data/generated_schema_validations.gemspec +1 -1
- data/lib/generated_schema_validations/capistrano_tasks.rb +66 -0
- data/lib/generated_schema_validations/dump_checker.rb +14 -0
- data/lib/generated_schema_validations/dumper.rb +11 -4
- data/lib/generated_schema_validations/table.rb +1 -1
- data/lib/generated_schema_validations/tasks.rb +12 -0
- data/lib/generated_schema_validations/template.rb +4 -2
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5eb0b94787c5c2fa3dd63dfd3b0f60f15b4b109813ffcc9839bb28491eb11924
|
|
4
|
+
data.tar.gz: 247d7ce6faf3829e0710ed5c6ed1d962b7ffc5e3e2b7baeb72b0b44d69f6887b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8d7baeb772e414b39dd83be6e1bbd40af2494b227de222c6c3ed907ea5b2598d976cfde3c5f74df57280413366b3ec194f9b8324bba71ec772cead68e1b3c311
|
|
7
|
+
data.tar.gz: 7d87b3e7dfe1392ff49871f362658abcf712484c7f89bacf0124d52cb5c06cf18196ea25a5649b9d70fccbdba9b69cc9a81587caab8a9abd7fda292292c31d35
|
data/README.md
CHANGED
|
@@ -97,6 +97,21 @@ You can watch changes on `schema_validations.rb` to understand the generated val
|
|
|
97
97
|
|
|
98
98
|
## Changelog
|
|
99
99
|
|
|
100
|
+
### 0.5.1
|
|
101
|
+
|
|
102
|
+
* raise info about where-unique conditions only in local envs
|
|
103
|
+
|
|
104
|
+
### 0.5
|
|
105
|
+
|
|
106
|
+
* Enables automatic testing after deployment using Capistrano to compare the online database with the local one and automatically warn of any differences.
|
|
107
|
+
|
|
108
|
+
```ruby
|
|
109
|
+
# Add to Capfile
|
|
110
|
+
|
|
111
|
+
require 'generated_schema_validations/capistrano_tasks'
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
|
|
100
115
|
### 0.4
|
|
101
116
|
|
|
102
117
|
* JSON and JSONB fields can have an empty hash and still be considered present
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
namespace :generated_schema_validations do
|
|
4
|
+
desc 'compare remove dump with local variant'
|
|
5
|
+
task :compare_dumper do
|
|
6
|
+
on roles(:app) do
|
|
7
|
+
begin
|
|
8
|
+
require 'diff/lcs'
|
|
9
|
+
require 'diff/lcs/hunk'
|
|
10
|
+
diff_lcs_available = true
|
|
11
|
+
rescue LoadError
|
|
12
|
+
diff_lcs_available = false
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
local_file = 'app/models/concerns/schema_validations.rb'
|
|
16
|
+
local_content = File.read(local_file).strip
|
|
17
|
+
|
|
18
|
+
within release_path do
|
|
19
|
+
with(
|
|
20
|
+
rails_env: fetch(:rails_env),
|
|
21
|
+
rails_groups: fetch(:rails_assets_groups),
|
|
22
|
+
disable_database_environment_check: 1
|
|
23
|
+
) do
|
|
24
|
+
dump_output = capture(:rake, 'db:validation_dump_direct').strip
|
|
25
|
+
|
|
26
|
+
if dump_output != local_content
|
|
27
|
+
warn '❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌'
|
|
28
|
+
warn 'The online version of the automatically generated validations differs from the local version.'
|
|
29
|
+
warn 'Please check immediately.'
|
|
30
|
+
|
|
31
|
+
if diff_lcs_available
|
|
32
|
+
old_lines = local_content.lines
|
|
33
|
+
new_lines = dump_output.lines
|
|
34
|
+
diffs = Diff::LCS.diff(old_lines, new_lines)
|
|
35
|
+
|
|
36
|
+
if diffs.any?
|
|
37
|
+
info '----- DIFF START -----'
|
|
38
|
+
|
|
39
|
+
file_length_difference = 0
|
|
40
|
+
|
|
41
|
+
diffs.each do |piece|
|
|
42
|
+
hunk = Diff::LCS::Hunk.new(
|
|
43
|
+
old_lines, new_lines, piece,
|
|
44
|
+
3, # context lines
|
|
45
|
+
file_length_difference
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
file_length_difference = hunk.file_length_difference
|
|
49
|
+
|
|
50
|
+
info hunk.diff(:unified)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
info '----- DIFF END -----'
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
warn '❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌'
|
|
57
|
+
else
|
|
58
|
+
info '✔ Schema OK'
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
after 'deploy:publishing', 'generated_schema_validations:compare_dumper'
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class GeneratedSchemaValidations::DumpChecker < GeneratedSchemaValidations::Dumper
|
|
4
|
+
def self.read_schema_content
|
|
5
|
+
stream = StringIO.new
|
|
6
|
+
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
|
|
7
|
+
stream.rewind
|
|
8
|
+
stream.read
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def write_schema_validations(template_ruby)
|
|
12
|
+
puts template_ruby
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -2,12 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
class GeneratedSchemaValidations::Dumper
|
|
4
4
|
def self.generate
|
|
5
|
-
return unless Rails.env.development?
|
|
6
|
-
|
|
7
5
|
file = Tempfile.new(['schema', '.rb'])
|
|
8
6
|
begin
|
|
9
|
-
schema_content =
|
|
10
|
-
schema_content.gsub!(/ActiveRecord::Schema(\[[^\]]+\])?/, 'GeneratedSchemaValidations::Dumper')
|
|
7
|
+
schema_content = read_schema_content.gsub(/ActiveRecord::Schema(\[[^\]]+\])?/, self.name)
|
|
11
8
|
raise 'The scheme is not well-formed.' if schema_content.include?('ActiveRecord')
|
|
12
9
|
|
|
13
10
|
file.write(schema_content)
|
|
@@ -19,6 +16,10 @@ class GeneratedSchemaValidations::Dumper
|
|
|
19
16
|
end
|
|
20
17
|
end
|
|
21
18
|
|
|
19
|
+
def self.read_schema_content
|
|
20
|
+
File.read(Rails.root.join('db/schema.rb'))
|
|
21
|
+
end
|
|
22
|
+
|
|
22
23
|
def self.define(info = {}, &block)
|
|
23
24
|
new.define(info, &block)
|
|
24
25
|
end
|
|
@@ -34,6 +35,12 @@ class GeneratedSchemaValidations::Dumper
|
|
|
34
35
|
end.join
|
|
35
36
|
template_ruby.gsub!("#{indention_spaces}TABLE_VALIDATIONS", table_validations_ruby)
|
|
36
37
|
|
|
38
|
+
write_schema_validations(template_ruby)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def write_schema_validations(template_ruby)
|
|
42
|
+
return unless Rails.env.development?
|
|
43
|
+
|
|
37
44
|
File.write(Rails.root.join('app/models/concerns/schema_validations.rb'), template_ruby)
|
|
38
45
|
end
|
|
39
46
|
|
|
@@ -151,7 +151,7 @@ class GeneratedSchemaValidations::Table
|
|
|
151
151
|
return unless index_options[:unique]
|
|
152
152
|
return unless names.all? { |name| name.to_s.in?(@column_names) }
|
|
153
153
|
|
|
154
|
-
if
|
|
154
|
+
if index_options[:where]
|
|
155
155
|
@bad_indexes.push(names.map(&:to_s))
|
|
156
156
|
else
|
|
157
157
|
@unique_indexes.push(names.map(&:to_s))
|
|
@@ -6,3 +6,15 @@ Rake::Task['db:schema:dump'].enhance do
|
|
|
6
6
|
require_relative 'table'
|
|
7
7
|
GeneratedSchemaValidations::Dumper.generate
|
|
8
8
|
end
|
|
9
|
+
|
|
10
|
+
namespace :db do
|
|
11
|
+
desc 'Dump validations to stdout'
|
|
12
|
+
task validation_dump_direct: :environment do
|
|
13
|
+
require 'generated_schema_validations'
|
|
14
|
+
require_relative 'dumper'
|
|
15
|
+
require_relative 'dump_checker'
|
|
16
|
+
require_relative 'table'
|
|
17
|
+
|
|
18
|
+
GeneratedSchemaValidations::DumpChecker.generate
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -55,6 +55,8 @@ module SchemaValidations
|
|
|
55
55
|
unique_indexes.each do |names|
|
|
56
56
|
names.each do |name|
|
|
57
57
|
next if name.to_sym.in?(schema_validations_excluded_columns)
|
|
58
|
+
next unless defined?(Rails::Railtie)
|
|
59
|
+
next unless (Rails.env.development? || Rails.env.test?)
|
|
58
60
|
|
|
59
61
|
raise "Unique index with where clause is outside the scope of this gem.\n\n" \
|
|
60
62
|
"You can exclude this column: `schema_validations exclude: [:#{name}]`"
|
|
@@ -102,7 +104,7 @@ module SchemaValidations
|
|
|
102
104
|
def validate_each(record, attr_name, value)
|
|
103
105
|
return if value.nil?
|
|
104
106
|
return unless value.is_a?(DateTime) || value.is_a?(Time)
|
|
105
|
-
return if value.year.between?(-4711,
|
|
107
|
+
return if value.year.between?(-4711, 294_275) # see https://www.postgresql.org/docs/9.3/datatype-datetime.html
|
|
106
108
|
|
|
107
109
|
record.errors.add(attr_name, :invalid, options)
|
|
108
110
|
end
|
|
@@ -112,7 +114,7 @@ module SchemaValidations
|
|
|
112
114
|
def validate_each(record, attr_name, value)
|
|
113
115
|
return if value.nil?
|
|
114
116
|
return unless value.is_a?(Date)
|
|
115
|
-
return if value.year.between?(-4711,
|
|
117
|
+
return if value.year.between?(-4711, 5_874_896) # see https://www.postgresql.org/docs/9.3/datatype-datetime.html
|
|
116
118
|
|
|
117
119
|
record.errors.add(attr_name, :invalid, options)
|
|
118
120
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: generated_schema_validations
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Georg Limbach
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-12-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: After each migration it generates a file with some validations. Each
|
|
14
14
|
active record should include this file and can uns generated validations.
|
|
@@ -27,6 +27,8 @@ files:
|
|
|
27
27
|
- Rakefile
|
|
28
28
|
- generated_schema_validations.gemspec
|
|
29
29
|
- lib/generated_schema_validations.rb
|
|
30
|
+
- lib/generated_schema_validations/capistrano_tasks.rb
|
|
31
|
+
- lib/generated_schema_validations/dump_checker.rb
|
|
30
32
|
- lib/generated_schema_validations/dumper.rb
|
|
31
33
|
- lib/generated_schema_validations/railtie.rb
|
|
32
34
|
- lib/generated_schema_validations/table.rb
|