Skip to content

Commit 10787b9

Browse files
authored
Merge pull request #483 from Shopify/revert-456-pb-use-arel-for-conditions
Revert "Use Arel instead of String for AR Enumerator conditionals"
2 parents 2897431 + 6aa24b2 commit 10787b9

File tree

7 files changed

+24
-58
lines changed

7 files changed

+24
-58
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
### Main (unreleased)
22
Nil
33

4+
## v1.5.1 (May 29,2024)
5+
- [483](https://github.com/Shopify/job-iteration/pull/483) Reverts [#456 Use Arel instead of String for AR Enumerator conditionals](https://github.com/Shopify/job-iteration/pull/456)
6+
47
## v1.5.0 (May 29, 2024)
58
### Changes
69

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ GIT
77
PATH
88
remote: .
99
specs:
10-
job-iteration (1.5.0)
10+
job-iteration (1.5.1)
1111
activejob (>= 5.2)
1212

1313
GEM

lib/job-iteration/active_record_cursor.rb

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,12 @@ def initialize
1818
end
1919
end
2020

21-
def initialize(relation, columns, position = nil)
22-
@columns = columns
21+
def initialize(relation, columns = nil, position = nil)
22+
@columns = if columns
23+
Array(columns)
24+
else
25+
Array(relation.primary_key).map { |pk| "#{relation.table_name}.#{pk}" }
26+
end
2327
self.position = Array.wrap(position)
2428
raise ArgumentError, "Must specify at least one column" if columns.empty?
2529
if relation.joins_values.present? && !@columns.all? { |column| column.to_s.include?(".") }
@@ -30,7 +34,7 @@ def initialize(relation, columns, position = nil)
3034
raise ConditionNotSupportedError
3135
end
3236

33-
@base_relation = relation.reorder(*@columns)
37+
@base_relation = relation.reorder(@columns.join(","))
3438
@reached_end = false
3539
end
3640

@@ -50,10 +54,12 @@ def position=(position)
5054

5155
def update_from_record(record)
5256
self.position = @columns.map do |column|
53-
if ActiveRecord.version >= Gem::Version.new("7.1.0.alpha") && column.name == "id"
57+
method = column.to_s.split(".").last
58+
59+
if ActiveRecord.version >= Gem::Version.new("7.1.0.alpha") && method == "id"
5460
record.id_value
5561
else
56-
record.send(column.name)
62+
record.send(method.to_sym)
5763
end
5864
end
5965
end
@@ -83,14 +89,14 @@ def conditions
8389
i = @position.size - 1
8490
column = @columns[i]
8591
conditions = if @columns.size == @position.size
86-
column.gt(@position[i])
92+
"#{column} > ?"
8793
else
88-
column.gteq(@position[i])
94+
"#{column} >= ?"
8995
end
9096
while i > 0
9197
i -= 1
9298
column = @columns[i]
93-
conditions = column.gt(@position[i]).or(column.eq(@position[i]).and(conditions))
99+
conditions = "#{column} > ? OR (#{column} = ? AND (#{conditions}))"
94100
end
95101
ret = @position.reduce([conditions]) { |params, value| params << value << value }
96102
ret.pop

lib/job-iteration/active_record_enumerator.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ def initialize(relation, columns: nil, batch_size: 100, cursor: nil)
1111
@relation = relation
1212
@batch_size = batch_size
1313
@columns = if columns
14-
Array(columns).map { |col| relation.arel_table[col.to_sym] }
14+
Array(columns)
1515
else
16-
Array(relation.primary_key).map { |pk| relation.arel_table[pk.to_sym] }
16+
Array(relation.primary_key).map { |pk| "#{relation.table_name}.#{pk}" }
1717
end
1818
@cursor = cursor
1919
end
@@ -45,7 +45,7 @@ def size
4545

4646
def cursor_value(record)
4747
positions = @columns.map do |column|
48-
attribute_name = column.name.to_sym
48+
attribute_name = column.to_s.split(".").last
4949
column_value(record, attribute_name)
5050
end
5151
return positions.first if positions.size == 1
@@ -58,8 +58,8 @@ def finder_cursor
5858
end
5959

6060
def column_value(record, attribute)
61-
value = record.read_attribute(attribute)
62-
case record.class.columns_hash.fetch(attribute.to_s).type
61+
value = record.read_attribute(attribute.to_sym)
62+
case record.class.columns_hash.fetch(attribute).type
6363
when :datetime
6464
value.strftime(SQL_DATETIME_WITH_NSEC)
6565
else

lib/job-iteration/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# frozen_string_literal: true
22

33
module JobIteration
4-
VERSION = "1.5.0"
4+
VERSION = "1.5.1"
55
end

test/test_helper.rb

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -106,40 +106,6 @@ def assert_logged(message)
106106
end
107107
end
108108

109-
module ActiveRecordHelpers
110-
def assert_sql(*patterns_to_match, &block)
111-
captured_queries = []
112-
assert_nothing_raised do
113-
ActiveSupport::Notifications.subscribed(
114-
->(_name, _start_time, _end_time, _subscriber_id, payload) { captured_queries << payload[:sql] },
115-
"sql.active_record",
116-
&block
117-
)
118-
end
119-
120-
failed_patterns = []
121-
patterns_to_match.each do |pattern|
122-
failed_check = captured_queries.none? do |sql|
123-
case pattern
124-
when Regexp
125-
sql.match?(pattern)
126-
when String
127-
sql == pattern
128-
else
129-
raise ArgumentError, "#assert_sql encountered an unknown matcher #{pattern.inspect}"
130-
end
131-
end
132-
failed_patterns << pattern if failed_check
133-
end
134-
queries = captured_queries.empty? ? "" : "\nQueries:\n #{captured_queries.join("\n ")}"
135-
assert_predicate(
136-
failed_patterns,
137-
:empty?,
138-
"Query pattern(s) #{failed_patterns.map(&:inspect).join(", ")} not found.#{queries}",
139-
)
140-
end
141-
end
142-
143109
JobIteration.logger = Logger.new(IO::NULL)
144110
ActiveJob::Base.logger = Logger.new(IO::NULL)
145111

test/unit/active_record_enumerator_test.rb

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
module JobIteration
66
class ActiveRecordEnumeratorTest < IterationUnitTest
7-
include ActiveRecordHelpers
8-
97
SQL_TIME_FORMAT = "%Y-%m-%d %H:%M:%S.%N"
108
test "#records yields every record with their cursor position" do
119
enum = build_enumerator.records
@@ -135,13 +133,6 @@ class ActiveRecordEnumeratorTest < IterationUnitTest
135133
end
136134
end
137135

138-
test "enumerator paginates using integer conditionals for primary key when no columns are defined" do
139-
enum = build_enumerator(relation: Product.all, batch_size: 1).records
140-
assert_sql(/`products`\.`id` > 1/) do
141-
enum.take(2)
142-
end
143-
end
144-
145136
private
146137

147138
def build_enumerator(relation: Product.all, batch_size: 2, columns: nil, cursor: nil)

0 commit comments

Comments
 (0)