activerecord_with_progress 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c4d04878e26b39a84c4f04ce57f308dd381982ef
4
+ data.tar.gz: fc65313de25bf50dd08c23fe67c605e26b43e5c2
5
+ SHA512:
6
+ metadata.gz: b01db8a88432086cd0e062fcd3907dc02a0e7f90769557bdafb65e651ff1cc14226eb92ca45667844d9e385685b306823f283f5e9ae55ebe8f81b6990bd0e2a0
7
+ data.tar.gz: 2118b2f0ed0dc17b43d1e8ab4357e89437041681a0ecc63437903217272c747e88aa791edaf6aeb56f6608f879fb636907c070fdd58116b335a132c8cdbd026f
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ .ruby-version
11
+ .ruby-gemset
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in activerecord_with_progress.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Mike Bourgeous
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # ActiverecordWithProgress
2
+
3
+ Similar to other gems that provide progress bars for `Enumerable`, this gem
4
+ provides a progress bar for ActiveRecord relations. We use it for Rake tasks,
5
+ migrations, and console commands. Maybe it's useful to you, too.
6
+
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem 'activerecord_with_progress', github: 'deseretbook/activerecord_with_progress'
14
+ ```
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+
21
+ ## Usage
22
+
23
+ Provides `_with_progress` wrappers (via `method_missing`) for several common
24
+ ActiveRecord iteration methods. They should have, but are not guaranteed to
25
+ have, the same memory usage, computation requirements, and access patterns as
26
+ the methods they wrap.
27
+
28
+
29
+ ```ruby
30
+ SomeModel.all.each_with_progress do |record|
31
+ # Do something with the record
32
+ end
33
+
34
+ SomeModel.all.find_each_with_progress do |record|
35
+ # ...
36
+ end
37
+
38
+ SomeModel.all.each_with_index_and_progress do |record, index|
39
+ # ...
40
+ end
41
+
42
+ SomeModel.where(condition: true).each_with_index_and_progress do |record, index|
43
+ # ...
44
+ end
45
+
46
+ mapped = SomeModel.all.map_with_progress do |record|
47
+ # ...
48
+ end
49
+ ```
50
+
51
+ There's an option to catch errors and return them in a second return value:
52
+
53
+ ```ruby
54
+ # Returns the #each return value, and a Hash mapping failed records to exceptions
55
+ _, errors = SomeModel.all.each_with_progress(handle_errors: true) do |record|
56
+ raise 'Handled'
57
+ end
58
+
59
+ # Returns the map with nil for errors, and a Hash with exceptions.
60
+ mapped, errors = SomeModel.where(some: 'condition').map_with_progress(handle_errors: true) do |record|
61
+ raise 'Nil in the map'
62
+ end
63
+ ```
64
+
65
+ The `find_in_batches` method is a little bit tricker to work with:
66
+
67
+ ```ruby
68
+ # Need to override :total; I would use #find_each_with_progress instead.
69
+ query = SomeModel.where(query: 'parameters')
70
+ query.find_in_batches_with_progress(batch_size: 5, total: query.count / 5 + !) do |batch| puts batch.size end
71
+ ```
72
+
73
+
74
+ You can change the progress bar format from the colorful default. See the docs
75
+ for [ruby-progressbar](https://rubygems.org/gems/ruby-progressbar) for format
76
+ details.
77
+
78
+ ```ruby
79
+ ActiverecordWithProgress.progress_format = 'a ruby-progressbar format string'
80
+ ```
81
+
82
+
83
+ ## Development
84
+
85
+ After checking out the repo, run `bin/setup` to install dependencies. You can
86
+ also run `bin/console` for an interactive prompt that will allow you to
87
+ experiment.
88
+
89
+ To release a new version, update the version number in `version.rb`, and then
90
+ run `bundle exec rake release`, which will create a git tag for the version,
91
+ push git commits and tags, and push the `.gem` file to
92
+ [rubygems.org](https://rubygems.org).
93
+
94
+
95
+ ## Contributing
96
+
97
+ Bug reports and pull requests are welcome on GitHub at https://github.com/deseretbook/activerecord_with_progress.
98
+
99
+
100
+ ## License
101
+
102
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
103
+
104
+ This independent gem is not an official part of or endorsed add-on for ActiveRecord.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'activerecord_with_progress/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "activerecord_with_progress"
8
+ spec.version = ActiverecordWithProgress::VERSION
9
+ spec.authors = ["Deseret Book", "Mike Bourgeous"]
10
+ spec.email = ["webdev@deseretbook.com", "mike@mikebourgeous.com"]
11
+
12
+ spec.summary = %q{Adds methods to ActiveRecord::Relation for iterating with progress bars}
13
+ spec.homepage = "https://github.com/deseretbook/activerecord_with_progress"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.required_ruby_version = '1.9.3'
22
+
23
+ spec.add_dependency "activerecord", "~> 4.1"
24
+ spec.add_dependency "ruby-progressbar", "~> 1.7.5"
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.10"
27
+ spec.add_development_dependency "rake", "~> 10.0"
28
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "activerecord_with_progress"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,68 @@
1
+ require 'active_record'
2
+
3
+ module ActiverecordWithProgress
4
+ module ActiverecordRelation
5
+ # Adds a progress bar to iterator methods if _with_progress or
6
+ # _and_progress is appended to the method name. Arguments are passed
7
+ # through to the backing method, with options pulled from the last Hash in
8
+ # the argument list (if any). If only our own options are specified, the
9
+ # options hash will be deleted from the argument list (so no arguments will
10
+ # be passed to methods that expect no arguments, like #each).
11
+ #
12
+ # Options:
13
+ # :handle_errors - If true, returns two values: the original result and a
14
+ # Hash mapping records to errors.
15
+ # :total - Override the total count used by the progress bar.
16
+ def method_missing(method, *args)
17
+ name = method.to_s
18
+ if name.end_with?('_with_progress') || name.end_with?('_and_progress')
19
+ name = name.sub(/_(with|and)_progress$/, '')
20
+ iterate_with_progress(name, *args) do |*a|
21
+ yield *a
22
+ end
23
+ else
24
+ super
25
+ end
26
+ end
27
+
28
+ private
29
+ # Implements progress bar iteration and error handling. Calls the given
30
+ # +method+ with the given arguments, incrementing the progress bar each
31
+ # time the method yields.
32
+ def iterate_with_progress(method, *args)
33
+ options = args.reverse.detect{|a| a.is_a?(Hash)} || {}
34
+ total = options.delete(:total) || self.count
35
+ handle_errors = options.delete(:handle_errors)
36
+ args.delete(options) if options.empty?
37
+
38
+ progress = ActiverecordWithProgress.create(total: total)
39
+
40
+ if handle_errors
41
+ errors = {}
42
+
43
+ results = send(method, *args) do |*a|
44
+ progress.increment rescue nil
45
+
46
+ begin
47
+ yield *a
48
+ rescue => e
49
+ errors[a[0]] = e
50
+ nil
51
+ end
52
+ end
53
+
54
+ [ results, errors ]
55
+ else
56
+ send(method, *args) do |*a|
57
+ progress.increment rescue nil
58
+ yield *a
59
+ end
60
+ end
61
+
62
+ ensure
63
+ progress.finish if progress
64
+ end
65
+ end
66
+ end
67
+
68
+ ActiveRecord::Relation.include ActiverecordWithProgress::ActiverecordRelation
@@ -0,0 +1,3 @@
1
+ module ActiverecordWithProgress
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,28 @@
1
+ require "activerecord_with_progress/version"
2
+
3
+ require 'ruby-progressbar'
4
+
5
+ module ActiverecordWithProgress
6
+ # Default progress bar format (see ruby-progressbar documentation).
7
+ DEFAULT_FORMAT = "\e[36m%a \e[35m%e\e[0m \e[34m[\e[1m%B\e[0;34m] %c/%C %p%%\e[0m"
8
+ @progress_format = DEFAULT_FORMAT
9
+
10
+ class << self
11
+ # Set or retrieve the format string used for progress bars.
12
+ attr_accessor :progress_format
13
+
14
+ # Creates a progress bar with our own default options and format, unless
15
+ # overrided by the options hash. Also works around Spring's removal of
16
+ # IO.console for Rails apps that use Spring by setting :length.
17
+ def create(options=nil)
18
+ opts = {
19
+ format: progress_format,
20
+ length: (IO.console.winsize[1] rescue nil) || ENV['columns'] || `tput cols`
21
+ }
22
+ opts.merge!(options) if options.is_a?(Hash)
23
+ ProgressBar.create(opts)
24
+ end
25
+ end
26
+ end
27
+
28
+ require 'activerecord_with_progress/activerecord_relation'
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activerecord_with_progress
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Deseret Book
8
+ - Mike Bourgeous
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2016-03-16 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '4.1'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '4.1'
28
+ - !ruby/object:Gem::Dependency
29
+ name: ruby-progressbar
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: 1.7.5
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: 1.7.5
42
+ - !ruby/object:Gem::Dependency
43
+ name: bundler
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '1.10'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '1.10'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rake
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '10.0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '10.0'
70
+ description:
71
+ email:
72
+ - webdev@deseretbook.com
73
+ - mike@mikebourgeous.com
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - ".gitignore"
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - activerecord_with_progress.gemspec
84
+ - bin/console
85
+ - bin/setup
86
+ - lib/activerecord_with_progress.rb
87
+ - lib/activerecord_with_progress/activerecord_relation.rb
88
+ - lib/activerecord_with_progress/version.rb
89
+ homepage: https://github.com/deseretbook/activerecord_with_progress
90
+ licenses:
91
+ - MIT
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - '='
100
+ - !ruby/object:Gem::Version
101
+ version: 1.9.3
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 2.5.1
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: Adds methods to ActiveRecord::Relation for iterating with progress bars
113
+ test_files: []