From 4c3e11d30a9295404c54646a5d0c8a47991c35d4 Mon Sep 17 00:00:00 2001 From: Marc-Andre Lafortune Date: Tue, 4 Feb 2014 01:51:21 -0500 Subject: Remove obsolete line (was needed for Ruby 1.8.7 support) --- activesupport/test/core_ext/enumerable_test.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/activesupport/test/core_ext/enumerable_test.rb b/activesupport/test/core_ext/enumerable_test.rb index 6781e3c20e..6c32622e71 100644 --- a/activesupport/test/core_ext/enumerable_test.rb +++ b/activesupport/test/core_ext/enumerable_test.rb @@ -8,7 +8,6 @@ class SummablePayment < Payment end class EnumerableTests < ActiveSupport::TestCase - Enumerator = [].each.class class GenericEnumerable include Enumerable -- cgit v1.2.3 From 39b2cc1900b0cb10057d46d7e2ed54f8e0b1e26f Mon Sep 17 00:00:00 2001 From: Marc-Andre Lafortune Date: Tue, 4 Feb 2014 01:57:27 -0500 Subject: Remove obsolete test (builtin group_by is now used) --- activesupport/test/core_ext/enumerable_test.rb | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/activesupport/test/core_ext/enumerable_test.rb b/activesupport/test/core_ext/enumerable_test.rb index 6c32622e71..6b3e8364c5 100644 --- a/activesupport/test/core_ext/enumerable_test.rb +++ b/activesupport/test/core_ext/enumerable_test.rb @@ -20,26 +20,6 @@ class EnumerableTests < ActiveSupport::TestCase end end - def test_group_by - names = %w(marcel sam david jeremy) - klass = Struct.new(:name) - objects = (1..50).map do - klass.new names.sample - end - - enum = GenericEnumerable.new(objects) - grouped = enum.group_by { |object| object.name } - - grouped.each do |name, group| - assert group.all? { |person| person.name == name } - end - - assert_equal objects.uniq.map(&:name), grouped.keys - assert({}.merge(grouped), "Could not convert ActiveSupport::OrderedHash into Hash") - assert_equal Enumerator, enum.group_by.class - assert_equal grouped, enum.group_by.each(&:name) - end - def test_sums enum = GenericEnumerable.new([5, 15, 10]) assert_equal 30, enum.sum -- cgit v1.2.3 From 4499ab5fdeca46416cfc4a50a376eba4eb8e16b4 Mon Sep 17 00:00:00 2001 From: Marc-Andre Lafortune Date: Tue, 4 Feb 2014 01:47:40 -0500 Subject: Strengthen test with different nb of rows and columns --- activerecord/test/cases/result_test.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/activerecord/test/cases/result_test.rb b/activerecord/test/cases/result_test.rb index b6c583dbf5..edaeb85211 100644 --- a/activerecord/test/cases/result_test.rb +++ b/activerecord/test/cases/result_test.rb @@ -5,14 +5,16 @@ module ActiveRecord def result Result.new(['col_1', 'col_2'], [ ['row 1 col 1', 'row 1 col 2'], - ['row 2 col 1', 'row 2 col 2'] + ['row 2 col 1', 'row 2 col 2'], + ['row 3 col 1', 'row 3 col 2'], ]) end def test_to_hash_returns_row_hashes assert_equal [ {'col_1' => 'row 1 col 1', 'col_2' => 'row 1 col 2'}, - {'col_1' => 'row 2 col 1', 'col_2' => 'row 2 col 2'} + {'col_1' => 'row 2 col 1', 'col_2' => 'row 2 col 2'}, + {'col_1' => 'row 3 col 1', 'col_2' => 'row 3 col 2'}, ], result.to_hash end -- cgit v1.2.3 From d37f395be86d131d0218dadd189771f99b06874f Mon Sep 17 00:00:00 2001 From: Marc-Andre Lafortune Date: Wed, 29 Jan 2014 14:53:54 -0500 Subject: Return sized enumerator from Batches#find_in_batches --- activerecord/CHANGELOG.md | 6 ++++++ activerecord/lib/active_record/relation/batches.rb | 13 +++++++++---- activerecord/test/cases/batches_test.rb | 10 ++++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index d14b5b27f8..4bc31457c0 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,9 @@ +* `find_in_batches` now returns an `Enumerator` that can calculate its size. + + See also #13938. + + *Marc-André Lafortune* + * Make sure transaction state gets reset after a commit operation on the record. If a new transaction was open inside a callback, the record was loosing track diff --git a/activerecord/lib/active_record/relation/batches.rb b/activerecord/lib/active_record/relation/batches.rb index 666cef80a9..a06da659cb 100644 --- a/activerecord/lib/active_record/relation/batches.rb +++ b/activerecord/lib/active_record/relation/batches.rb @@ -96,17 +96,22 @@ module ActiveRecord # the batch sizes. def find_in_batches(options = {}) options.assert_valid_keys(:start, :batch_size) - return to_enum(:find_in_batches, options) unless block_given? relation = self + start = options[:start] + batch_size = options[:batch_size] || 1000 + + unless block_given? + return to_enum(:find_in_batches, options) do + total = start ? where(table[primary_key].gteq(start)).size : size + (total - 1).div(batch_size) + 1 + end + end if logger && (arel.orders.present? || arel.taken.present?) logger.warn("Scoped order and limit are ignored, it's forced to be batch order and batch size") end - start = options[:start] - batch_size = options[:batch_size] || 1000 - relation = relation.reorder(batch_order).limit(batch_size) records = start ? relation.where(table[primary_key].gteq(start)).to_a : relation.to_a diff --git a/activerecord/test/cases/batches_test.rb b/activerecord/test/cases/batches_test.rb index 8216d74cb3..4ee09a640e 100644 --- a/activerecord/test/cases/batches_test.rb +++ b/activerecord/test/cases/batches_test.rb @@ -191,4 +191,14 @@ class EachTest < ActiveRecord::TestCase end end end + + if Enumerator.method_defined? :size + def test_find_in_batches_should_return_a_sized_enumerator + assert_equal 11, Post.find_in_batches(:batch_size => 1).size + assert_equal 6, Post.find_in_batches(:batch_size => 2).size + assert_equal 4, Post.find_in_batches(:batch_size => 2, :start => 4).size + assert_equal 4, Post.find_in_batches(:batch_size => 3).size + assert_equal 1, Post.find_in_batches(:batch_size => 10_000).size + end + end end -- cgit v1.2.3 From 13d2696c10726afecd393753fcac88c5a9907d8c Mon Sep 17 00:00:00 2001 From: Marc-Andre Lafortune Date: Wed, 29 Jan 2014 15:42:07 -0500 Subject: Return sized enumerator from Batches#find_each --- activerecord/CHANGELOG.md | 8 +++++++- activerecord/lib/active_record/relation/batches.rb | 4 +++- activerecord/lib/active_record/result.rb | 2 +- activerecord/test/cases/batches_test.rb | 8 ++++++++ activerecord/test/cases/result_test.rb | 6 ++++++ activesupport/lib/active_support/core_ext/enumerable.rb | 2 +- 6 files changed, 26 insertions(+), 4 deletions(-) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 4bc31457c0..af723c61bd 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,4 +1,10 @@ -* `find_in_batches` now returns an `Enumerator` that can calculate its size. +<<<<<<< HEAD +* `find_in_batches`, `find_each` now + return an `Enumerator` that can calculate its size. +======= +* `find_in_batches`, `find_each`, `Result#each` now returns an `Enumerator` + that can calculate its size. +>>>>>>> 5863938... Return sized enumerator from Result#each See also #13938. diff --git a/activerecord/lib/active_record/relation/batches.rb b/activerecord/lib/active_record/relation/batches.rb index a06da659cb..29fc150b3d 100644 --- a/activerecord/lib/active_record/relation/batches.rb +++ b/activerecord/lib/active_record/relation/batches.rb @@ -52,7 +52,9 @@ module ActiveRecord records.each { |record| yield record } end else - enum_for :find_each, options + enum_for :find_each, options do + options[:start] ? where(table[primary_key].gteq(options[:start])).size : size + end end end diff --git a/activerecord/lib/active_record/result.rb b/activerecord/lib/active_record/result.rb index 469451e2f4..228b2aa60f 100644 --- a/activerecord/lib/active_record/result.rb +++ b/activerecord/lib/active_record/result.rb @@ -54,7 +54,7 @@ module ActiveRecord if block_given? hash_rows.each { |row| yield row } else - hash_rows.to_enum + hash_rows.to_enum { @rows.size } end end diff --git a/activerecord/test/cases/batches_test.rb b/activerecord/test/cases/batches_test.rb index 4ee09a640e..c12fa03015 100644 --- a/activerecord/test/cases/batches_test.rb +++ b/activerecord/test/cases/batches_test.rb @@ -35,6 +35,14 @@ class EachTest < ActiveRecord::TestCase end end + if Enumerator.method_defined? :size + def test_each_should_return_a_sized_enumerator + assert_equal 11, Post.find_each(:batch_size => 1).size + assert_equal 5, Post.find_each(:batch_size => 2, :start => 7).size + assert_equal 11, Post.find_each(:batch_size => 10_000).size + end + end + def test_each_enumerator_should_execute_one_query_per_batch assert_queries(@total + 1) do Post.find_each(:batch_size => 1).with_index do |post, index| diff --git a/activerecord/test/cases/result_test.rb b/activerecord/test/cases/result_test.rb index edaeb85211..2131b32a0c 100644 --- a/activerecord/test/cases/result_test.rb +++ b/activerecord/test/cases/result_test.rb @@ -30,5 +30,11 @@ module ActiveRecord assert_kind_of Integer, index end end + + if Enumerator.method_defined? :size + def test_each_without_block_returns_a_sized_enumerator + assert_equal 3, result.each.size + end + end end end diff --git a/activesupport/lib/active_support/core_ext/enumerable.rb b/activesupport/lib/active_support/core_ext/enumerable.rb index 4501b7ff58..a2dec41c87 100644 --- a/activesupport/lib/active_support/core_ext/enumerable.rb +++ b/activesupport/lib/active_support/core_ext/enumerable.rb @@ -35,7 +35,7 @@ module Enumerable if block_given? Hash[map { |elem| [yield(elem), elem] }] else - to_enum :index_by + to_enum(:index_by) { size } end end -- cgit v1.2.3 From a476020567a47f5fbec3629707d5bf31b400a284 Mon Sep 17 00:00:00 2001 From: Marc-Andre Lafortune Date: Tue, 4 Feb 2014 02:18:03 -0500 Subject: Return sized enumerator from Enumerable#index_by --- activerecord/CHANGELOG.md | 7 +------ activesupport/lib/active_support/core_ext/enumerable.rb | 2 +- activesupport/test/core_ext/enumerable_test.rb | 4 ++++ 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index af723c61bd..f1d51b9de1 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,10 +1,5 @@ -<<<<<<< HEAD -* `find_in_batches`, `find_each` now +* `find_in_batches`, `find_each`, `Result#each` and `Enumerable#index_by` now return an `Enumerator` that can calculate its size. -======= -* `find_in_batches`, `find_each`, `Result#each` now returns an `Enumerator` - that can calculate its size. ->>>>>>> 5863938... Return sized enumerator from Result#each See also #13938. diff --git a/activesupport/lib/active_support/core_ext/enumerable.rb b/activesupport/lib/active_support/core_ext/enumerable.rb index a2dec41c87..1343beb87a 100644 --- a/activesupport/lib/active_support/core_ext/enumerable.rb +++ b/activesupport/lib/active_support/core_ext/enumerable.rb @@ -35,7 +35,7 @@ module Enumerable if block_given? Hash[map { |elem| [yield(elem), elem] }] else - to_enum(:index_by) { size } + to_enum(:index_by) { size if respond_to?(:size) } end end diff --git a/activesupport/test/core_ext/enumerable_test.rb b/activesupport/test/core_ext/enumerable_test.rb index 6b3e8364c5..6fcf6e8743 100644 --- a/activesupport/test/core_ext/enumerable_test.rb +++ b/activesupport/test/core_ext/enumerable_test.rb @@ -73,6 +73,10 @@ class EnumerableTests < ActiveSupport::TestCase assert_equal({ 5 => Payment.new(5), 15 => Payment.new(15), 10 => Payment.new(10) }, payments.index_by { |p| p.price }) assert_equal Enumerator, payments.index_by.class + if Enumerator.method_defined? :size + assert_equal nil, payments.index_by.size + assert_equal 42, (1..42).index_by.size + end assert_equal({ 5 => Payment.new(5), 15 => Payment.new(15), 10 => Payment.new(10) }, payments.index_by.each { |p| p.price }) end -- cgit v1.2.3