Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
张重言
rails
提交
84fe7b7d
R
rails
项目概览
张重言
/
rails
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rails
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
84fe7b7d
编写于
2月 05, 2014
作者:
R
Rafael Mendonça França
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #13938 from marcandre/sized_enumerator
Sized enumerator
上级
1df4dcf7
a4760205
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
53 addition
and
30 deletion
+53
-30
activerecord/CHANGELOG.md
activerecord/CHANGELOG.md
+7
-0
activerecord/lib/active_record/relation/batches.rb
activerecord/lib/active_record/relation/batches.rb
+12
-5
activerecord/lib/active_record/result.rb
activerecord/lib/active_record/result.rb
+1
-1
activerecord/test/cases/batches_test.rb
activerecord/test/cases/batches_test.rb
+18
-0
activerecord/test/cases/result_test.rb
activerecord/test/cases/result_test.rb
+10
-2
activesupport/lib/active_support/core_ext/enumerable.rb
activesupport/lib/active_support/core_ext/enumerable.rb
+1
-1
activesupport/test/core_ext/enumerable_test.rb
activesupport/test/core_ext/enumerable_test.rb
+4
-21
未找到文件。
activerecord/CHANGELOG.md
浏览文件 @
84fe7b7d
*
`find_in_batches`
,
`find_each`
,
`Result#each`
and
`Enumerable#index_by`
now
return 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
...
...
activerecord/lib/active_record/relation/batches.rb
浏览文件 @
84fe7b7d
...
...
@@ -52,7 +52,9 @@ def find_each(options = {})
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
...
...
@@ -96,17 +98,22 @@ def find_each(options = {})
# 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
...
...
activerecord/lib/active_record/result.rb
浏览文件 @
84fe7b7d
...
...
@@ -54,7 +54,7 @@ def each
if
block_given?
hash_rows
.
each
{
|
row
|
yield
row
}
else
hash_rows
.
to_enum
hash_rows
.
to_enum
{
@rows
.
size
}
end
end
...
...
activerecord/test/cases/batches_test.rb
浏览文件 @
84fe7b7d
...
...
@@ -35,6 +35,14 @@ def test_each_should_return_an_enumerator_if_no_block_is_present
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
|
...
...
@@ -191,4 +199,14 @@ def test_find_in_batches_should_return_an_enumerator
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
activerecord/test/cases/result_test.rb
浏览文件 @
84fe7b7d
...
...
@@ -5,14 +5,16 @@ class ResultTest < ActiveRecord::TestCase
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
...
...
@@ -28,5 +30,11 @@ def test_each_without_block_returns_an_enumerator
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
activesupport/lib/active_support/core_ext/enumerable.rb
浏览文件 @
84fe7b7d
...
...
@@ -35,7 +35,7 @@ def index_by
if
block_given?
Hash
[
map
{
|
elem
|
[
yield
(
elem
),
elem
]
}]
else
to_enum
:index_by
to_enum
(
:index_by
)
{
size
if
respond_to?
(
:size
)
}
end
end
...
...
activesupport/test/core_ext/enumerable_test.rb
浏览文件 @
84fe7b7d
...
...
@@ -8,7 +8,6 @@ def +(p) self.class.new(price + p.price) end
end
class
EnumerableTests
<
ActiveSupport
::
TestCase
Enumerator
=
[].
each
.
class
class
GenericEnumerable
include
Enumerable
...
...
@@ -21,26 +20,6 @@ def each
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
...
...
@@ -94,6 +73,10 @@ def test_index_by
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
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录