traceindex 0.0.1 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e1976ad785be5c111087d12387e9a84df779ec397bc278e3824c9fdf66343140
4
- data.tar.gz: 9585e24b1aff78526e791572ae31401ed47dbb243aae0a4044657bc9263a5753
3
+ metadata.gz: b0a76e873f9bb112b3cd1f98613af8aa41754e426943e22fef117254b1a1309c
4
+ data.tar.gz: 98cd2a6ab6c7cd985648edc1310cad7197e444b7bb497e6fb4c698fb958a9d95
5
5
  SHA512:
6
- metadata.gz: b7af461287ee4ab0e7c95ef037b618082603a539ba55057b60f0728bea43635fe6c40388553c7c04796d138caecca37d9fa0eac15b5e550cb2faf236d864bba1
7
- data.tar.gz: 9f51f3ae65db56ef36c5cc2b1d616fa48c9e5cc7e3a71af1ca06dcceb5ab58837cd2cabcd87278cecbd525a6da6f8b0c01035610b178cad39b0ed9b48c44140f
6
+ metadata.gz: b7b05e1ccfd3f5a79adc80bc3b0412b19dc8ee47b725fa8f9d1ffe5a8c8f9fa4400d05a88465dd2fdc0c32fbe09c9e5d437697a02a72c5caaf3b93ecb1208335
7
+ data.tar.gz: ed7118e1fd8b2aa65da7422f04963bfeacab40d516d64f79f683b14888be31637b641ad6891866d638f38a64e91e70cdc5f991e2aa683f8410306dd8a98f1442
@@ -0,0 +1,52 @@
1
+ version: 2.1
2
+
3
+ executors:
4
+ default:
5
+ working_directory: ~/app
6
+ docker:
7
+ - image: circleci/ruby:2.6
8
+ environment:
9
+ DB_USER: 'root'
10
+ DB_PASS: 'root'
11
+ DB_HOST: '127.0.0.1'
12
+ - image: circleci/mysql:8-ram
13
+ environment:
14
+ MYSQL_ROOT_PASSWORD: root
15
+ MYSQL_DATABASE: traceindex_test
16
+ command: [--default-authentication-plugin=mysql_native_password]
17
+
18
+ commands:
19
+ setup_bundle:
20
+ steps:
21
+ - restore_cache:
22
+ key: bundle-{{ checksum "traceindex.gemspec" }}
23
+ - run:
24
+ name: install dependencies
25
+ command: |
26
+ bundle install --jobs=4 --retry=3 --path vendor/bundle
27
+ - save_cache:
28
+ key: bundle-{{ checksum "traceindex.gemspec" }}
29
+ paths:
30
+ - vendor/bundle
31
+
32
+ wait_for_db:
33
+ steps:
34
+ - run:
35
+ name: Wait for DB
36
+ command: dockerize -wait tcp://127.0.0.1:3306 -timeout 1m
37
+
38
+ jobs:
39
+ test:
40
+ executor: default
41
+ steps:
42
+ - checkout
43
+ - setup_bundle
44
+ - wait_for_db
45
+ - run: bundle exec rspec ./spec
46
+
47
+ workflows:
48
+ version: 2
49
+
50
+ test:
51
+ jobs:
52
+ - test
data/.gitignore CHANGED
@@ -3,4 +3,3 @@
3
3
  Gemfile.lock
4
4
  pkg/*
5
5
  *.log
6
- spec/database.yml
data/README.md CHANGED
@@ -29,18 +29,27 @@ If you want the rake task to fail when errors are found.
29
29
  % FAIL_ON_ERROR=1 rake traceindex
30
30
  ```
31
31
 
32
+ If you want the rake task to ignore foreign_keys.
33
+
34
+ ```
35
+ % IGNORE_FOREIGN_KEY=1 rake traceindex
36
+ ```
37
+
32
38
  ## How do I tell it to ignore columns?
33
39
 
34
40
  Create a .traceindex.yaml or .traceindex.yml file in your root directory.
35
41
 
36
42
  ```yaml
43
+ ignore_tables:
44
+ - action_mailbox_inbound_emails
45
+ - action_text_rich_texts
46
+ - active_storage_attachments
47
+ - active_storage_blobs
48
+ - active_storage_variant_records
37
49
  ignore_columns:
38
50
  - users.created_user_id
39
- ignore_models:
40
- - ActiveStorage::Blob
41
- - ActiveStorage::Attachment
42
- - ActionText::RichText
43
- - ActionMailbox::InboundEmail
51
+ ignore_foreign_keys:
52
+ - users.created_user_id
44
53
  ```
45
54
 
46
55
  ## Copyright
@@ -3,10 +3,21 @@ task traceindex: :environment do
3
3
  traceindex = Traceindex.new(Rails.application)
4
4
  column_names = traceindex.missing_index_column_names
5
5
 
6
- if column_names.size > 0
6
+ unless column_names.empty?
7
7
  puts "Missing index columns (#{column_names.size}):"
8
8
  column_names.each { |column| puts " #{column}" }
9
+ end
10
+
11
+ if ENV['IGNORE_FOREIGN_KEY'].nil?
12
+ fk_column_names = traceindex.missing_foreign_keys
13
+
14
+ unless fk_column_names.empty?
15
+ puts "Missing foreign keys (#{fk_column_names.size}):"
16
+ fk_column_names.each { |column| puts " #{column}" }
17
+ end
18
+ end
9
19
 
10
- raise 'Missing indexes detected.' if ENV['FAIL_ON_ERROR']
20
+ if ENV['FAIL_ON_ERROR'] && (!column_names.empty? || !fk_column_names.empty?)
21
+ raise 'Missing indexes detected.'
11
22
  end
12
23
  end
data/lib/traceindex.rb CHANGED
@@ -8,17 +8,11 @@ class Traceindex
8
8
  end
9
9
 
10
10
  def initialize(app)
11
- @app = app
12
- @ignore_models = []
13
- @ignore_columns = []
14
-
15
- (config["ignore_models"] || []).each do |ignored_model|
16
- @ignore_models << ignored_model
17
- end
18
-
19
- (config["ignore_columns"] || []).each do |ignored_column|
20
- @ignore_columns << ignored_column
21
- end
11
+ @app = app
12
+ @ignore_models = (config["ignore_models"] || [])
13
+ @ignore_columns = (config["ignore_columns"] || [])
14
+ @ignore_foreign_keys = (config["ignore_foreign_keys"] || [])
15
+ @ignore_tables = (config["ignore_tables"] || [])
22
16
  end
23
17
 
24
18
  def missing_index_column_names
@@ -41,6 +35,25 @@ class Traceindex
41
35
  end
42
36
  end
43
37
 
38
+ def missing_foreign_keys
39
+ models.each.with_object([]) do |model, missing_columns|
40
+ id_columns = model.columns.select {|column| column.name.end_with?("_id") }
41
+
42
+ foreign_keys = ActiveRecord::Base.connection.foreign_keys(model.table_name)
43
+
44
+ id_columns.each do |id_column|
45
+ if @ignore_foreign_keys.include?("#{model.table_name}.#{id_column.name}")
46
+ next
47
+ end
48
+
49
+ next unless foreign_keys.none? { |index| index.column == id_column.name }
50
+ missing_columns << "#{model.table_name}.#{id_column.name}"
51
+ end
52
+ rescue => e
53
+ puts e.message
54
+ end
55
+ end
56
+
44
57
  private
45
58
 
46
59
  def config_filename
@@ -56,7 +69,7 @@ class Traceindex
56
69
 
57
70
  @app.eager_load!
58
71
  @models ||= ActiveRecord::Base.descendants.reject(&:abstract_class).reject do |model|
59
- @ignore_models.include?(model.name)
72
+ @ignore_models.include?(model.name) || @ignore_tables.include?(model.table_name)
60
73
  end
61
74
  end
62
75
  end
data/spec/app.rb CHANGED
@@ -12,13 +12,13 @@ module DummyApp
12
12
  end
13
13
 
14
14
  ActiveRecord::Base.establish_connection(
15
- YAML.load(File.read('spec/database.yml'))['test']
15
+ YAML.load(ERB.new(File.read('spec/database.yml')).result)['test']
16
16
  )
17
17
 
18
18
  ActiveRecord::Schema.define version: 0 do
19
19
  create_table :users, force: true do |t|
20
- t.integer :created_user_id, index: true
21
- t.integer :updated_user_id, index: false
20
+ t.references :created_user, foreign_key: { to_table: :users }
21
+ t.integer :updated_user_id, index: false
22
22
  end
23
23
  end
24
24
 
data/spec/database.yml ADDED
@@ -0,0 +1,18 @@
1
+ default: &default
2
+ adapter: mysql2
3
+ encoding: utf8mb4
4
+ charset: utf8mb4
5
+ collation: utf8mb4_general_ci
6
+ pool: 5
7
+ username: <%= ENV.fetch("DB_USER") { 'root' } %>
8
+ password: <%= ENV.fetch("DB_PASS") { '' } %>
9
+ host: <%= ENV.fetch("DB_HOST") { '127.0.0.1' } %>
10
+ socket: /tmp/mysql.sock
11
+
12
+ development:
13
+ <<: *default
14
+ database: traceindex_development
15
+
16
+ test:
17
+ <<: *default
18
+ database: traceindex_test
@@ -7,30 +7,110 @@ describe Traceindex do
7
7
  expect(Traceindex::VERSION).not_to be nil
8
8
  end
9
9
 
10
+ let(:traceindex) { Traceindex.new(Rails.application) }
11
+
12
+ after { File.delete '.traceindex.yml' if File.exists? '.traceindex.yml' }
13
+
10
14
  describe '#missing_index_column_names' do
11
15
  it 'missing index found.' do
12
- traceindex = Traceindex.new(Rails.application)
13
16
  expect(traceindex.missing_index_column_names).to eq(['users.updated_user_id'])
14
17
  end
15
18
 
16
- context 'If you have a configuration file' do
19
+ context 'If you have a configuration file(ignore_columns)' do
17
20
  before do
18
21
  File.open '.traceindex.yml', 'w' do |file|
19
22
  file.puts 'ignore_columns:'
20
23
  file.puts ' - users.updated_user_id'
24
+ end
25
+ end
26
+
27
+ it 'missing index not found.' do
28
+ expect(traceindex.missing_index_column_names).to eq([])
29
+ end
30
+ end
31
+
32
+ context 'If you have a configuration file(ignore_models)' do
33
+ before do
34
+ File.open '.traceindex.yml', 'w' do |file|
21
35
  file.puts 'ignore_models:'
22
36
  file.puts ' - User'
23
37
  end
24
38
  end
25
39
 
26
- after do
27
- File.delete '.traceindex.yml'
40
+ it 'missing index not found.' do
41
+ expect(traceindex.missing_index_column_names).to eq([])
42
+ end
43
+ end
44
+
45
+ context 'If you have a configuration file(ignore_tables)' do
46
+ before do
47
+ File.open '.traceindex.yml', 'w' do |file|
48
+ file.puts 'ignore_tables:'
49
+ file.puts ' - users'
50
+ end
28
51
  end
29
52
 
30
53
  it 'missing index not found.' do
31
- traceindex = Traceindex.new(Rails.application)
32
54
  expect(traceindex.missing_index_column_names).to eq([])
33
55
  end
34
56
  end
57
+
58
+ context 'If you have a configuration file(ignore_foreign_keys)' do
59
+ before do
60
+ File.open '.traceindex.yml', 'w' do |file|
61
+ file.puts 'ignore_foreign_keys:'
62
+ file.puts ' - users.updated_user_id'
63
+ end
64
+ end
65
+
66
+ it 'missing index exists.' do
67
+ expect(traceindex.missing_index_column_names).to eq(['users.updated_user_id'])
68
+ end
69
+ end
70
+ end
71
+
72
+ describe '#missing_foreign_keys' do
73
+ it 'missing index found.' do
74
+ expect(traceindex.missing_foreign_keys).to eq(['users.updated_user_id'])
75
+ end
76
+
77
+ context 'If you have a configuration file(ignore_columns)' do
78
+ before do
79
+ File.open '.traceindex.yml', 'w' do |file|
80
+ file.puts 'ignore_columns:'
81
+ file.puts ' - users.updated_user_id'
82
+ end
83
+ end
84
+
85
+ it 'missing foreign keys exists.' do
86
+ expect(traceindex.missing_foreign_keys).to eq(['users.updated_user_id'])
87
+ end
88
+ end
89
+
90
+ context 'If you have a configuration file(ignore_foreign_keys)' do
91
+ before do
92
+ File.open '.traceindex.yml', 'w' do |file|
93
+ file.puts 'ignore_foreign_keys:'
94
+ file.puts ' - users.updated_user_id'
95
+ end
96
+ end
97
+
98
+ it 'missing foreign keys not found.' do
99
+ expect(traceindex.missing_foreign_keys).to eq([])
100
+ end
101
+ end
102
+
103
+ context 'If you have a configuration file(ignore_models)' do
104
+ before do
105
+ File.open '.traceindex.yml', 'w' do |file|
106
+ file.puts 'ignore_models:'
107
+ file.puts ' - User'
108
+ end
109
+ end
110
+
111
+ it 'missing foreign keys not found.' do
112
+ expect(traceindex.missing_foreign_keys).to eq([])
113
+ end
114
+ end
35
115
  end
36
116
  end
data/traceindex.gemspec CHANGED
@@ -2,7 +2,7 @@ $:.push File.expand_path('lib', __dir__)
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'traceindex'
5
- s.version = '0.0.1'
5
+ s.version = '0.1.0'
6
6
  s.platform = Gem::Platform::RUBY
7
7
  s.authors = ['Akira Kusumoto']
8
8
  s.email = ['akirakusumo10@gmail.com']
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: traceindex
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Akira Kusumoto
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-17 00:00:00.000000000 Z
11
+ date: 2023-03-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -74,6 +74,7 @@ executables: []
74
74
  extensions: []
75
75
  extra_rdoc_files: []
76
76
  files:
77
+ - ".circleci/config.yml"
77
78
  - ".gitignore"
78
79
  - Gemfile
79
80
  - MIT-LICENSE
@@ -82,7 +83,7 @@ files:
82
83
  - lib/tasks/traceindex.rake
83
84
  - lib/traceindex.rb
84
85
  - spec/app.rb
85
- - spec/database.yml.sample
86
+ - spec/database.yml
86
87
  - spec/spec_helper.rb
87
88
  - spec/traceroute_spec.rb
88
89
  - traceindex.gemspec
@@ -90,7 +91,7 @@ homepage: https://github.com/bluerabbit/traceindex
90
91
  licenses:
91
92
  - MIT
92
93
  metadata: {}
93
- post_install_message:
94
+ post_install_message:
94
95
  rdoc_options: []
95
96
  require_paths:
96
97
  - lib
@@ -105,12 +106,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
105
106
  - !ruby/object:Gem::Version
106
107
  version: '0'
107
108
  requirements: []
108
- rubygems_version: 3.0.3
109
- signing_key:
109
+ rubygems_version: 3.3.7
110
+ signing_key:
110
111
  specification_version: 4
111
112
  summary: A Rake task that helps you find the missing indexes for your Rails app
112
113
  test_files:
113
114
  - spec/app.rb
114
- - spec/database.yml.sample
115
+ - spec/database.yml
115
116
  - spec/spec_helper.rb
116
117
  - spec/traceroute_spec.rb
@@ -1,15 +0,0 @@
1
- default: &default
2
- adapter: mysql2
3
- encoding: utf8
4
- pool: 5
5
- username: root
6
- password:
7
- socket: /tmp/mysql.sock
8
-
9
- development:
10
- <<: *default
11
- database: traceindex_development
12
-
13
- test:
14
- <<: *default
15
- database: traceindex_test