4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
# File 'lib/composite_primary_keys/relation/batches.rb', line 4
def in_batches(of: 1000, start: nil, finish: nil, load: false, error_on_ignore: nil)
relation = self
unless block_given?
return BatchEnumerator.new(of: of, start: start, finish: finish, relation: self)
end
if arel.orders.present? || arel.taken.present?
act_on_order_or_limit_ignored(error_on_ignore)
end
relation = relation.reorder(batch_order).limit(of)
relation = apply_limits(relation, start, finish)
batch_relation = relation
loop do
if load
records = batch_relation.records
ids = records.map(&:id)
yielded_relation = self.where(cpk_in_predicate(table, primary_keys, ids))
yielded_relation.load_records(records)
else
ids = batch_relation.pluck(*Array(primary_keys))
yielded_relation = self.where(cpk_in_predicate(table, primary_keys, ids))
end
break if ids.empty?
primary_key_offset = ids.last
raise ArgumentError.new("Primary key not included in the custom select clause") unless primary_key_offset
yield yielded_relation
break if ids.length < of
batch_relation = if composite?
query = prefixes(primary_key.zip(primary_key_offset)).map do |kvs|
and_clause = kvs.each_with_index.map do |(k, v), i|
if i == kvs.length - 1
table[k].gt(v)
else
table[k].eq(v)
end
end.reduce(:and)
Arel::Nodes::Grouping.new(and_clause)
end.reduce(:or)
relation.where(query)
else
relation.where(arel_attribute(primary_key).gt(primary_key_offset))
end
end
end
|