counter_cache_update 0.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c9fdec978994bcd0e8a2fc20b35c99f3e0ea7c4b
4
+ data.tar.gz: ed8efce81568e503dfa5bbee9afb49e693c5eb48
5
+ SHA512:
6
+ metadata.gz: 7d0a2ee8c5a1015d1add9559a0adddaa5064be6f0d66a0043239ea2011822c21ff9db9287dc511c9b6183a8761f85d4b99e66a3d6b87d3ee59bc4c7dc6883def
7
+ data.tar.gz: e792bccd9c7cd79cee134cecdb919d1ac3f90cafe7b88e3345b125fab3225b4f3134e1f49ed47185c545d4271c2fd1f5a8ec5ec07e205a4c220c3fd03d0ec56c
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2018 kaspernj
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # CounterCacheUpdate
2
+ Short description and motivation.
3
+
4
+ ## Installation
5
+ Add this line to your application's Gemfile:
6
+
7
+ ```ruby
8
+ gem "counter_cache_update"
9
+ ```
10
+
11
+ And then execute:
12
+ ```bash
13
+ $ bundle
14
+ ```
15
+
16
+ ## Usage
17
+
18
+ Call the main service like this:
19
+ ```ruby
20
+ CounterCacheUpdate::UpdateService.execute!
21
+ ```
22
+
23
+ ## Contributing
24
+ Contribution directions go here.
25
+
26
+ ## License
27
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,28 @@
1
+ begin
2
+ require "bundler/setup"
3
+ rescue LoadError
4
+ puts "You must `gem install bundler` and `bundle install` to run rake tasks"
5
+ end
6
+
7
+ require "rdoc/task"
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = "rdoc"
11
+ rdoc.title = "CounterCacheUpdate"
12
+ rdoc.options << "--line-numbers"
13
+ rdoc.rdoc_files.include("README.md")
14
+ rdoc.rdoc_files.include("lib/**/*.rb")
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("spec/dummy/Rakefile", __dir__)
18
+ load "rails/tasks/engine.rake"
19
+
20
+
21
+ load "rails/tasks/statistics.rake"
22
+
23
+ if Rails.env.development? || Rails.env.test?
24
+ require "best_practice_project"
25
+ BestPracticeProject.load_tasks
26
+ end
27
+
28
+ require "bundler/gem_tasks"
@@ -0,0 +1,2 @@
1
+ //= link_directory ../javascripts/counter_cache_update .js
2
+ //= link_directory ../stylesheets/counter_cache_update .css
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,3 @@
1
+ class CounterCacheUpdate::ApplicationController < ActionController::Base
2
+ protect_from_forgery with: :exception
3
+ end
@@ -0,0 +1,2 @@
1
+ module CounterCacheUpdate::ApplicationHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ class CounterCacheUpdate::ApplicationJob < ActiveJob::Base
2
+ end
@@ -0,0 +1,4 @@
1
+ class CounterCacheUpdate::ApplicationMailer < ActionMailer::Base
2
+ default from: "from@example.com"
3
+ layout "mailer"
4
+ end
@@ -0,0 +1,3 @@
1
+ class CounterCacheUpdate::ApplicationRecord < ActiveRecord::Base
2
+ self.abstract_class = true
3
+ end
@@ -0,0 +1,49 @@
1
+ class CounterCacheUpdate::TableUpdatorService < ServicePattern::Service
2
+ attr_reader :model_class, :reflection
3
+
4
+ def initialize(reflection:)
5
+ @reflection = reflection
6
+ @model_class = @reflection.class_name.constantize
7
+ end
8
+
9
+ def execute!
10
+ model_class.connection.execute(sql)
11
+ ServicePattern::Response.new(success: true)
12
+ end
13
+
14
+ private
15
+
16
+ def column_name
17
+ @column_name ||= proc do
18
+ if reflection.options[:counter_cache] == true
19
+ "#{reflection.active_record.name.pluralize.underscore}_count"
20
+ else
21
+ reflection.options[:counter_cache]
22
+ end
23
+ end.call
24
+ end
25
+
26
+ def count_sql
27
+ "SELECT COUNT(*) FROM #{reflection_table_name} WHERE #{reflection_table_name}.#{reflection_primary_key} = #{table_name}.#{primary_key}"
28
+ end
29
+
30
+ def primary_key
31
+ model_class.primary_key
32
+ end
33
+
34
+ def reflection_primary_key
35
+ reflection.active_record.primary_key
36
+ end
37
+
38
+ def reflection_table_name
39
+ reflection.active_record.table_name
40
+ end
41
+
42
+ def sql
43
+ "UPDATE #{table_name} SET #{column_name} = (#{count_sql})"
44
+ end
45
+
46
+ def table_name
47
+ model_class.table_name
48
+ end
49
+ end
@@ -0,0 +1,37 @@
1
+ class CounterCacheUpdate::UpdateService < ServicePattern::Service
2
+ attr_reader :use_progress_bar
3
+
4
+ def initialize(use_progress_bar: false)
5
+ @use_progress_bar = use_progress_bar
6
+ end
7
+
8
+ def execute!
9
+ Rails.application.eager_load!
10
+
11
+ if use_progress_bar
12
+ require "progress_bar"
13
+ @progress_bar = ProgressBar.new(model_classes.size)
14
+ end
15
+
16
+ update_relationships!
17
+ ServicePattern::Response.new(success: true)
18
+ end
19
+
20
+ private
21
+
22
+ def update_relationships!
23
+ model_classes.each do |model_class|
24
+ @progress_bar&.increment!
25
+
26
+ model_class.reflections.each do |_name, reflection|
27
+ next unless reflection.macro.to_sym == :belongs_to
28
+ next unless reflection.options[:counter_cache]
29
+ CounterCacheUpdate::TableUpdatorService.execute!(reflection: reflection)
30
+ end
31
+ end
32
+ end
33
+
34
+ def model_classes
35
+ @model_classes ||= ActiveRecord::Base.descendants
36
+ end
37
+ end
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Counter cache update</title>
5
+ <%= stylesheet_link_tag "counter_cache_update/application", media: "all" %>
6
+ <%= javascript_include_tag "counter_cache_update/application" %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
data/config/routes.rb ADDED
@@ -0,0 +1,2 @@
1
+ CounterCacheUpdate::Engine.routes.draw do
2
+ end
@@ -0,0 +1,5 @@
1
+ module CounterCacheUpdate; end
2
+
3
+ class CounterCacheUpdate::Engine < ::Rails::Engine
4
+ isolate_namespace CounterCacheUpdate
5
+ end
@@ -0,0 +1,3 @@
1
+ module CounterCacheUpdate
2
+ VERSION = "0.0.0".freeze
3
+ end
@@ -0,0 +1,6 @@
1
+ require "counter_cache_update/engine"
2
+ require "service_pattern"
3
+
4
+ module CounterCacheUpdate
5
+ # Your code goes here...
6
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :counter_cache_update do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: counter_cache_update
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - kaspernj
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-03-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 5.1.5
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 5.1.5
27
+ - !ruby/object:Gem::Dependency
28
+ name: service_pattern
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.0.3
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.0.3
41
+ description: Scans all your models and updates all counter caches with optimised SQL.
42
+ email:
43
+ - kaspernj@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - MIT-LICENSE
49
+ - README.md
50
+ - Rakefile
51
+ - app/assets/config/counter_cache_update_manifest.js
52
+ - app/assets/javascripts/counter_cache_update/application.js
53
+ - app/assets/stylesheets/counter_cache_update/application.css
54
+ - app/controllers/counter_cache_update/application_controller.rb
55
+ - app/helpers/counter_cache_update/application_helper.rb
56
+ - app/jobs/counter_cache_update/application_job.rb
57
+ - app/mailers/counter_cache_update/application_mailer.rb
58
+ - app/models/counter_cache_update/application_record.rb
59
+ - app/services/counter_cache_update/table_updator_service.rb
60
+ - app/services/counter_cache_update/update_service.rb
61
+ - app/views/layouts/counter_cache_update/application.html.erb
62
+ - config/routes.rb
63
+ - lib/counter_cache_update.rb
64
+ - lib/counter_cache_update/engine.rb
65
+ - lib/counter_cache_update/version.rb
66
+ - lib/tasks/counter_cache_update_tasks.rake
67
+ homepage: https://github.com/kaspernj/counter_cache_update
68
+ licenses:
69
+ - MIT
70
+ metadata: {}
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ requirements: []
86
+ rubyforge_project:
87
+ rubygems_version: 2.6.13
88
+ signing_key:
89
+ specification_version: 4
90
+ summary: Scans all your models and updates all counter caches with optimised SQL.
91
+ test_files: []