care_bert 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +90 -0
- data/Rakefile +0 -4
- data/lib/care_bert/configuration.rb +2 -4
- data/lib/care_bert/railtie.rb +6 -8
- data/lib/care_bert/reporter.rb +7 -15
- data/lib/care_bert/sniffer.rb +22 -36
- data/lib/care_bert/version.rb +1 -1
- data/lib/care_bert.rb +1 -6
- data/lib/tasks/care_bert_tasks.rake +10 -12
- data/test/care_bert_test.rb +1 -1
- data/test/dummy/config/application.rb +1 -2
- data/test/dummy/config/initializers/cookies_serializer.rb +1 -1
- data/test/test_helper.rb +4 -4
- metadata +21 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 44ac9bdf896ba7635c558b5dd428fdbb6da1a150
|
4
|
+
data.tar.gz: b35e9622dd7cdaff3149ec5a3dfa2b4223bfee19
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a2fd39550a50b302d6a514ff235adea3521cccd38f60df16cd02885c227b8d493f5ba9bfad483f4c1b0f9f5ff2a1c2a5fbf7b8cdced26361ef0923796525f27b
|
7
|
+
data.tar.gz: cc138bb6e51dc7cb7b94c393dae6accc06f6e70cdbcd87568a7a5c2dc5f7ca31aebc37b9fc049c181d3f46d6db45ff4e3fd33c8b0075129b089b4c61ea559537
|
data/README.md
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
# CareBert
|
2
|
+
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/care_bert.svg)](http://badge.fury.io/rb/care_bert)
|
4
|
+
|
5
|
+
This project rocks and uses MIT-LICENSE.
|
6
|
+
|
7
|
+
Any features missing? write your suggestions as issue or create a pull-request.
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
### Overview of provided Rake Tasks
|
12
|
+
|
13
|
+
```shell
|
14
|
+
rake -T
|
15
|
+
|
16
|
+
rake care_bert:missing_assocs # Checks all belongs_to-associations of all instances and checks presence of model if foreign-key is set
|
17
|
+
rake care_bert:table_integrity # Tries to load all instances and tracks failures on load
|
18
|
+
rake care_bert:validate_models # Run model validations on all model records in database
|
19
|
+
```
|
20
|
+
|
21
|
+
|
22
|
+
### care\_bert:table\_integrity
|
23
|
+
Tries to load all instances and tracks failures on load. This might occur, if there is invalid data on a serialized field (e.g. Hash) that can't be loaded by ActiveRecord.
|
24
|
+
|
25
|
+
**It is strongly recommended to perform this rake task before any other one.**
|
26
|
+
|
27
|
+
```shell
|
28
|
+
rake care_bert:table_integrity
|
29
|
+
|
30
|
+
-- records - broken instances - model --
|
31
|
+
5182 - 0 - Tweet
|
32
|
+
314 - 0 - Photo
|
33
|
+
278 - 0 - User
|
34
|
+
```
|
35
|
+
|
36
|
+
|
37
|
+
### care\_bert:missing\_assocs
|
38
|
+
Checks all belongs_to-associations of all instances and checks presence of model if foreign-key is set.
|
39
|
+
|
40
|
+
```shell
|
41
|
+
rake care_bert:missing_assocs
|
42
|
+
|
43
|
+
Daniel-DL-1307:paij-backend danielloy$ rake care_bert:missing_assocs
|
44
|
+
-- records - broken instances - model --
|
45
|
+
5182 - 0 - Tweet
|
46
|
+
314 - 1 - Photo
|
47
|
+
278 - 0 - User
|
48
|
+
|
49
|
+
Listing ids of missing model-instances of assocs:
|
50
|
+
-------------------------------------------------------
|
51
|
+
- Photo --------------
|
52
|
+
>> affected_instances: [1]
|
53
|
+
- 1 >> {:user=>1231234}
|
54
|
+
```
|
55
|
+
|
56
|
+
### care\_bert:validate\_models
|
57
|
+
Run model validations on all model records in database. Sums up all ids of failing models by the combined validation-errors.
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
```shell
|
62
|
+
rake care_bert:validate_models
|
63
|
+
|
64
|
+
-- records - broken instances - model --
|
65
|
+
5182 - 0 - Tweet
|
66
|
+
314 - 0 - Photo
|
67
|
+
278 - 7 - User
|
68
|
+
|
69
|
+
User:
|
70
|
+
["Name is missing"] >> [18, 42, 58, 95]
|
71
|
+
["Name is missing", "E-Mail contains invalid characters"] >> [12, 128, 229]
|
72
|
+
```
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
## Agenda
|
77
|
+
|
78
|
+
- [ ] Add Tests (with edge cases, securing rails3 and rails4 compat)
|
79
|
+
- [ ] integrate Travis CI
|
80
|
+
- [ ] fancy badges..
|
81
|
+
- [ ] \(optional:) create tasks, that delete troubling model-instances
|
82
|
+
- [ ] apply rubocop via git-hook
|
83
|
+
- [ ] apply generic primary_key as lookup instead of static "id"
|
84
|
+
|
85
|
+
|
86
|
+
## Credits
|
87
|
+
|
88
|
+
This gem is also inspired from: http://blog.hasmanythrough.com/2006/8/27/validate-all-your-records
|
89
|
+
https://github.com/joshsusser
|
90
|
+
|
data/Rakefile
CHANGED
@@ -14,9 +14,6 @@ RDoc::Task.new(:rdoc) do |rdoc|
|
|
14
14
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
15
|
end
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
17
|
Bundler::GemHelper.install_tasks
|
21
18
|
|
22
19
|
require 'rake/testtask'
|
@@ -28,5 +25,4 @@ Rake::TestTask.new(:test) do |t|
|
|
28
25
|
t.verbose = false
|
29
26
|
end
|
30
27
|
|
31
|
-
|
32
28
|
task default: :test
|
data/lib/care_bert/railtie.rb
CHANGED
data/lib/care_bert/reporter.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
module CareBert
|
2
|
-
|
3
2
|
module Reporter
|
4
|
-
|
5
|
-
|
6
|
-
puts "-- records - smells - model --"
|
3
|
+
def self.validate_models(report)
|
4
|
+
puts '-- records - smells - model --'
|
7
5
|
report.each_key do |klass_name|
|
8
6
|
printf "%10d - %10d - %s\n", report[klass_name][:total], report[klass_name][:smell_count], klass_name
|
9
7
|
end
|
@@ -22,11 +20,10 @@ module CareBert
|
|
22
20
|
puts
|
23
21
|
end
|
24
22
|
end
|
25
|
-
|
26
23
|
end
|
27
24
|
|
28
|
-
def self.table_integrity
|
29
|
-
puts
|
25
|
+
def self.table_integrity(report)
|
26
|
+
puts '-- records - broken instances - model --'
|
30
27
|
anything_broken = false
|
31
28
|
report.each_key do |klass_name|
|
32
29
|
printf "%10d - %16d - %s\n", report[klass_name][:total], report[klass_name][:broken_instances].count, klass_name
|
@@ -41,12 +38,10 @@ module CareBert
|
|
41
38
|
printf " - %s\n >> %s\n\n", klass_name, report[klass_name][:broken_instances]
|
42
39
|
end
|
43
40
|
end
|
44
|
-
|
45
41
|
end
|
46
42
|
|
47
|
-
|
48
|
-
|
49
|
-
puts "-- records - broken instances - model --"
|
43
|
+
def self.missing_assocs(report)
|
44
|
+
puts '-- records - broken instances - model --'
|
50
45
|
anything_broken = false
|
51
46
|
report.each_key do |klass_name|
|
52
47
|
printf "%10d - %16d - %s\n", report[klass_name][:total], report[klass_name][:smell_count], klass_name
|
@@ -60,7 +55,7 @@ module CareBert
|
|
60
55
|
report.each_key do |klass_name|
|
61
56
|
if report[klass_name][:errors].present?
|
62
57
|
puts "- #{klass_name} --------------"
|
63
|
-
sorted_keys = report[klass_name][:errors].keys.
|
58
|
+
sorted_keys = report[klass_name][:errors].keys.map(&:to_i).sort
|
64
59
|
puts ">> affected_instances: #{sorted_keys}"
|
65
60
|
sorted_keys.each do |record_id|
|
66
61
|
printf " - %s >> %s\n", record_id, report[klass_name][:errors][record_id.to_s]
|
@@ -68,9 +63,6 @@ module CareBert
|
|
68
63
|
end
|
69
64
|
end
|
70
65
|
end
|
71
|
-
|
72
66
|
end
|
73
|
-
|
74
67
|
end
|
75
|
-
|
76
68
|
end
|
data/lib/care_bert/sniffer.rb
CHANGED
@@ -1,28 +1,25 @@
|
|
1
1
|
module CareBert
|
2
|
-
|
3
2
|
module Sniffer
|
4
|
-
|
5
3
|
# returns hash with data
|
6
4
|
def self.check_table_integrity
|
7
|
-
result =
|
5
|
+
result = {}
|
8
6
|
|
9
7
|
chunk_size = CareBert::Configuration::CHUNK_SIZE
|
10
8
|
|
11
9
|
Dir.glob(Rails.root.join('/app/models/**/*.rb')).each { |file| require file }
|
12
|
-
ActiveRecord::Base.descendants.select { |c| c.base_class == c}.sort_by(&:name).each do |klass|
|
10
|
+
ActiveRecord::Base.descendants.select { |c| c.base_class == c }.sort_by(&:name).each do |klass|
|
13
11
|
total = klass.count
|
14
12
|
|
15
13
|
result[klass.name] = Hash.new
|
16
14
|
result[klass.name][:total] = total
|
17
15
|
result[klass.name][:broken_instances] = []
|
18
16
|
|
19
|
-
|
20
17
|
(total / chunk_size + 1).times do |i|
|
21
18
|
begin
|
22
|
-
chunk = klass.find(:all, :
|
19
|
+
chunk = klass.find(:all, offset: (i * chunk_size), limit: chunk_size)
|
23
20
|
chunk.to_a
|
24
21
|
rescue
|
25
|
-
#puts "Crashed while loading model #{klass.name}"
|
22
|
+
# puts "Crashed while loading model #{klass.name}"
|
26
23
|
track_unloadable_instances(klass, offset..(offset + chunk_size - 1)).each do |id|
|
27
24
|
result[klass.name][:broken_instances] << id
|
28
25
|
end
|
@@ -33,67 +30,63 @@ module CareBert
|
|
33
30
|
result
|
34
31
|
end
|
35
32
|
|
36
|
-
|
37
|
-
|
38
33
|
# inspired from from: http://blog.hasmanythrough.com/2006/8/27/validate-all-your-records
|
39
34
|
def self.validate_models
|
40
|
-
result =
|
35
|
+
result = {}
|
41
36
|
|
42
37
|
chunk_size = CareBert::Configuration::CHUNK_SIZE
|
43
38
|
|
44
39
|
Dir.glob(Rails.root.join('/app/models/**/*.rb')).each { |file| require file }
|
45
40
|
ActiveRecord::Base.descendants.select { |c| c.base_class == c }.sort_by(&:name).each do |klass|
|
46
41
|
result[klass.name] = {
|
47
|
-
|
48
|
-
|
49
|
-
|
42
|
+
total: klass.count,
|
43
|
+
smell_count: 0, # max klass.count
|
44
|
+
errors: Hash.new # max klass.count
|
50
45
|
}
|
51
46
|
|
52
|
-
|
53
47
|
(result[klass.name][:total] / chunk_size + 1).times do |i|
|
54
|
-
chunk = klass.find(:all, :
|
48
|
+
chunk = klass.find(:all, offset: (i * chunk_size), limit: chunk_size)
|
55
49
|
chunk.reject(&:valid?).each do |record|
|
56
50
|
result[klass.name][:smell_count] += 1
|
57
51
|
errors_key = record.errors.full_messages || ['unknown validation error!?']
|
58
|
-
unless result[klass.name][:errors].
|
52
|
+
unless result[klass.name][:errors].key? errors_key
|
59
53
|
result[klass.name][:errors][errors_key] = []
|
60
54
|
end
|
61
55
|
result[klass.name][:errors][errors_key] << record.id
|
62
56
|
end rescue nil
|
63
|
-
|
57
|
+
|
58
|
+
# TODO: check in which constellation the list to sort might ever be nil
|
59
|
+
result[klass.name][:errors].select { |err| !err.nil? }.each { |err| result[klass.name][:errors][err].sort! } rescue nil
|
64
60
|
end
|
65
61
|
end
|
66
62
|
|
67
63
|
result
|
68
64
|
end
|
69
65
|
|
70
|
-
|
71
|
-
|
72
66
|
def self.check_missing_assocs
|
73
|
-
result =
|
67
|
+
result = {}
|
74
68
|
|
75
69
|
chunk_size = CareBert::Configuration::CHUNK_SIZE
|
76
70
|
|
77
71
|
Dir.glob(Rails.root.join('/app/models/**/*.rb')).each { |file| require file }
|
78
72
|
ActiveRecord::Base.descendants.select { |c| c.base_class == c }.sort_by(&:name).each do |klass|
|
79
73
|
result[klass.name] = {
|
80
|
-
|
81
|
-
|
82
|
-
|
74
|
+
total: klass.count,
|
75
|
+
smell_count: 0, # max klass.count
|
76
|
+
errors: Hash.new # max klass.count
|
83
77
|
}
|
84
78
|
|
85
|
-
|
86
79
|
(result[klass.name][:total] / chunk_size + 1).times do |i|
|
87
|
-
chunk = klass.find(:all, :
|
80
|
+
chunk = klass.find(:all, offset: (i * chunk_size), limit: chunk_size)
|
88
81
|
chunk.each do |record|
|
89
82
|
|
90
83
|
failing_fields = {}
|
91
84
|
|
92
85
|
[:belongs_to].each do |assoc_type| # optional => :has_one
|
93
|
-
fields = klass.reflect_on_all_associations(assoc_type).
|
86
|
+
fields = klass.reflect_on_all_associations(assoc_type).map(&:name)
|
94
87
|
|
95
88
|
fields.each do |field|
|
96
|
-
#puts "Check #{klass.name} => #{field}"
|
89
|
+
# puts "Check #{klass.name} => #{field}"
|
97
90
|
|
98
91
|
id_field = "#{field}_id"
|
99
92
|
if record.respond_to?(id_field)
|
@@ -114,10 +107,7 @@ module CareBert
|
|
114
107
|
result
|
115
108
|
end
|
116
109
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
def self.track_unloadable_instances klass, id_range
|
110
|
+
def self.track_unloadable_instances(klass, id_range)
|
121
111
|
result = []
|
122
112
|
id_range.each do |id|
|
123
113
|
begin
|
@@ -128,9 +118,5 @@ module CareBert
|
|
128
118
|
end
|
129
119
|
result
|
130
120
|
end
|
131
|
-
|
132
|
-
|
133
121
|
end
|
134
|
-
|
135
|
-
|
136
|
-
end
|
122
|
+
end
|
data/lib/care_bert/version.rb
CHANGED
data/lib/care_bert.rb
CHANGED
@@ -2,15 +2,10 @@ require 'care_bert/configuration'
|
|
2
2
|
require 'care_bert/sniffer'
|
3
3
|
require 'care_bert/reporter'
|
4
4
|
|
5
|
-
|
6
5
|
module CareBert
|
7
|
-
|
8
|
-
|
9
6
|
# load Railtie if Rails exists
|
10
7
|
if defined?(Rails)
|
11
8
|
require 'care_bert/railtie'
|
12
|
-
#CareBert::Railtie.insert
|
9
|
+
# CareBert::Railtie.insert
|
13
10
|
end
|
14
|
-
|
15
|
-
|
16
11
|
end
|
@@ -1,33 +1,31 @@
|
|
1
1
|
require 'care_bert'
|
2
2
|
|
3
|
-
#desc "Explaining what the task does"
|
4
|
-
#task :care_bert do
|
3
|
+
# desc "Explaining what the task does"
|
4
|
+
# task :care_bert do
|
5
5
|
# # Task goes here
|
6
6
|
# puts "success"
|
7
|
-
#end
|
8
|
-
|
7
|
+
# end
|
9
8
|
|
10
9
|
# file: validate_models.rake
|
11
10
|
# task: rake db:validate_models
|
12
11
|
namespace :care_bert do
|
13
|
-
desc
|
14
|
-
task :
|
12
|
+
desc 'Run model validations on all model records in database'
|
13
|
+
task validate_models: :environment do
|
15
14
|
# ANALYZE all
|
16
15
|
report = CareBert::Sniffer.validate_models
|
17
16
|
CareBert::Reporter.validate_models report
|
18
17
|
end
|
19
18
|
|
20
|
-
desc
|
21
|
-
task :
|
19
|
+
desc 'Tries to load all instances and tracks failures on load'
|
20
|
+
task table_integrity: :environment do
|
22
21
|
report = CareBert::Sniffer.check_table_integrity
|
23
22
|
CareBert::Reporter.table_integrity report
|
24
23
|
end
|
25
24
|
|
26
|
-
desc
|
27
|
-
task :
|
25
|
+
desc 'Checks all belongs_to-associations of all instances and checks presence of model if foreign-key is set'
|
26
|
+
task missing_assocs: :environment do
|
28
27
|
report = CareBert::Sniffer.check_missing_assocs
|
29
28
|
CareBert::Reporter.missing_assocs report
|
30
29
|
end
|
31
30
|
|
32
|
-
|
33
|
-
end
|
31
|
+
end
|
data/test/care_bert_test.rb
CHANGED
@@ -3,7 +3,7 @@ require File.expand_path('../boot', __FILE__)
|
|
3
3
|
require 'rails/all'
|
4
4
|
|
5
5
|
Bundler.require(*Rails.groups)
|
6
|
-
require
|
6
|
+
require 'care_bert'
|
7
7
|
|
8
8
|
module Dummy
|
9
9
|
class Application < Rails::Application
|
@@ -20,4 +20,3 @@ module Dummy
|
|
20
20
|
# config.i18n.default_locale = :de
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
data/test/test_helper.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# Configure Rails Environment
|
2
|
-
ENV[
|
2
|
+
ENV['RAILS_ENV'] = 'test'
|
3
3
|
|
4
|
-
require File.expand_path(
|
5
|
-
require
|
4
|
+
require File.expand_path('../dummy/config/environment.rb', __FILE__)
|
5
|
+
require 'rails/test_help'
|
6
6
|
|
7
7
|
Rails.backtrace_cleaner.remove_silencers!
|
8
8
|
|
@@ -11,5 +11,5 @@ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
|
11
11
|
|
12
12
|
# Load fixtures from the engine
|
13
13
|
if ActiveSupport::TestCase.method_defined?(:fixture_path=)
|
14
|
-
ActiveSupport::TestCase.fixture_path = File.expand_path(
|
14
|
+
ActiveSupport::TestCase.fixture_path = File.expand_path('../fixtures', __FILE__)
|
15
15
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: care_bert
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Loy
|
@@ -12,12 +12,26 @@ date: 2014-10-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sqlite3
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
16
30
|
requirements:
|
17
31
|
- - ">="
|
18
32
|
- !ruby/object:Gem::Version
|
19
33
|
version: '0'
|
20
|
-
type: :
|
34
|
+
type: :development
|
21
35
|
prerelease: false
|
22
36
|
version_requirements: !ruby/object:Gem::Requirement
|
23
37
|
requirements:
|
@@ -25,7 +39,7 @@ dependencies:
|
|
25
39
|
- !ruby/object:Gem::Version
|
26
40
|
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
42
|
+
name: rubocop
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
45
|
- - ">="
|
@@ -38,7 +52,8 @@ dependencies:
|
|
38
52
|
- - ">="
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '0'
|
41
|
-
description:
|
55
|
+
description: CareBert analyzes the current items of your database and performs differing
|
56
|
+
validation and integrity tests.
|
42
57
|
email:
|
43
58
|
- loybert@gmail.com
|
44
59
|
executables: []
|
@@ -46,6 +61,7 @@ extensions: []
|
|
46
61
|
extra_rdoc_files: []
|
47
62
|
files:
|
48
63
|
- MIT-LICENSE
|
64
|
+
- README.md
|
49
65
|
- Rakefile
|
50
66
|
- lib/care_bert.rb
|
51
67
|
- lib/care_bert/configuration.rb
|
@@ -91,7 +107,7 @@ files:
|
|
91
107
|
- test/dummy/public/500.html
|
92
108
|
- test/dummy/public/favicon.ico
|
93
109
|
- test/test_helper.rb
|
94
|
-
homepage: https://github.com/loybert
|
110
|
+
homepage: https://github.com/loybert/care_bert
|
95
111
|
licenses:
|
96
112
|
- MIT
|
97
113
|
metadata: {}
|