Skip to content

Commit c71fd12

Browse files
committed
Increase speed of Table#to_csv when encoding is provided
If we set the encoding when we call Table#to_csv we do not need to go row by row to determine the encoding to use. This allows the use of CSV#generate_lines as a faster exporter.
1 parent 4a70610 commit c71fd12

File tree

2 files changed

+17
-3
lines changed

2 files changed

+17
-3
lines changed

lib/csv/table.rb

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,10 +1006,15 @@ def to_csv(write_headers: true, limit: nil, **options)
10061006
limit ||= @table.size
10071007
limit = @table.size + 1 + limit if limit < 0
10081008
limit = 0 if limit < 0
1009-
@table.first(limit).each do |row|
1010-
array.push(row.fields.to_csv(**options)) unless row.header_row?
1011-
end
10121009

1010+
if options[:encoding]
1011+
rows = @table.first(limit).select { |row| !row.header_row? }
1012+
array.push(CSV.generate_lines(rows, **options))
1013+
else
1014+
@table.first(limit).each do |row|
1015+
array.push(row.fields.to_csv(**options)) unless row.header_row?
1016+
end
1017+
end
10131018
array.join("")
10141019
end
10151020
alias_method :to_s, :to_csv

test/csv/test_table.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,15 @@ def test_to_csv_limit_negative_over
373373
CSV
374374
end
375375

376+
def test_to_csv_encoding
377+
rows = [ CSV::Row.new(%w{A}, ["\x00\xac".force_encoding("ASCII-8BIT")]),
378+
CSV::Row.new(%w{A}, ["\x00\xac"]) ]
379+
table = CSV::Table.new(rows)
380+
381+
assert_equal('UTF-8', table.to_csv(encoding: 'UTF-8').encoding.to_s)
382+
assert_raises(Encoding::CompatibilityError) {table.to_csv}
383+
end
384+
376385
def test_append
377386
# verify that we can chain the call
378387
assert_equal(@table, @table << [10, 11, 12])

0 commit comments

Comments
 (0)