Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[review] each_with_progress メソッドを追加 #44

Merged
merged 2 commits into from
Apr 19, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 20 additions & 11 deletions lib/dekiru/data_migration_operator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,31 @@ def duration
((self.ended_at || Time.current) - self.started_at)
end

def find_each_with_progress(target_scope, options = {})
total = options.delete(:total)
opt = {
format: '%a |%b>>%i| %p%% %t',
}.merge(options).merge(
total: total || target_scope.count,
output: stream
)
@pb = ::ProgressBar.create(opt)
target_scope.find_each do |target|
yield target
def with_progress(enum, options = {})
tkawa marked this conversation as resolved.
Show resolved Hide resolved
options = options.dup
options[:total] ||= ((enum.size == Float::INFINITY ? nil : enum.size) rescue nil)
options[:format] ||= options[:total] ? '%a |%b>>%i| %p%% %t' : '%a |%b>>%i| ??%% %t'
options[:output] ||= stream
tkawa marked this conversation as resolved.
Show resolved Hide resolved

@pb = ::ProgressBar.create(options)
enum.each do |item|
yield item
@pb.increment
end
@pb.finish
end

def find_each_with_progress(target_scope, options = {}, &block)
enum =
if target_scope.is_a?(ActiveRecord::Batches)
target_scope.find_each
else
# ActiveRecord由来のfind_eachでないと思われる場合は明示的にenumeratorに変換
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これがテストのDekiru::DummyRecordで失敗しないようにするためだけだとしたら、テストの方を直すほうが正攻法な気がしました。
あとでこれ読んでも何のための考慮か理解するのが難しそうだし、実際の利用上はまず必要のない分岐だろうなーと。

Copy link
Contributor Author

@tkawa tkawa Apr 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aki77
今までも find_each がないところで find_each を生やして使っている例があるんじゃないかと思って、テストを通すためもありますが互換性のためです。
仕様を
「target_scopeは『ブロック引数がなければenumeratorを返す』find_eachメソッドを持つ」
に変更するのであればテストもそのように変更しますがそれでいいですか?
(実際のところ分岐せず常に target_scope.enum_for(:find_each) としても問題なさそうですが)

https://github.com/search?q=org%3ASonicGarden+find_each_with_progress&type=code
https://github.com/SonicGarden/planet-producttimes/blob/792fd05ff22880c4816e6aa59b20f540e8e1f8d3/scripts/lib/import_jicfs_codes.rb#L16
https://github.com/SonicGarden/aelz/blob/07bae8c1c1e5a57cf981ba652f788e92bf217a12/script/maintenance/20240206_import_tour_resources.rb#L9
ざっと探すと2例ですがどちらもenumeratorを返すので動作はしそう。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

なるほどー。
手動実行用のスクリプトでしか使わない処理だし、gemの更新案内見逃したとしてもエラーで落ちたら新しいメソッド使うように書き換えればいいだけなので、わざわざ古い仕様を維持する必要はないかなーと思いました。

target_scope.enum_for(:find_each)
end
with_progress(enum, options, &block)
end

private

def current_transaction_open?
Expand Down