fastercsv 1.5.1 → 1.5.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +10 -0
- data/lib/faster_csv.rb +24 -15
- data/test/tc_csv_parsing.rb +4 -0
- data/test/tc_interface.rb +1 -1
- data/test/tc_table.rb +2 -0
- metadata +12 -5
data/CHANGELOG
CHANGED
@@ -2,6 +2,16 @@
|
|
2
2
|
|
3
3
|
Below is a complete listing of changes for each revision of FasterCSV.
|
4
4
|
|
5
|
+
== 1.5.3
|
6
|
+
|
7
|
+
* A bug fix from Timothy Elliott to return the new parser to its strict quote
|
8
|
+
tolerance.
|
9
|
+
|
10
|
+
== 1.5.2
|
11
|
+
|
12
|
+
* A bug fix to allow IO Exceptions to reach the calling code from Moses Hohman.
|
13
|
+
* Added support for <tt>:write_headers => false</tt> to Table.to_csv().
|
14
|
+
|
5
15
|
== 1.5.1
|
6
16
|
|
7
17
|
* A bug fix for deleting blank Table rows from Andy Hartford.
|
data/lib/faster_csv.rb
CHANGED
@@ -82,7 +82,7 @@ require "stringio"
|
|
82
82
|
#
|
83
83
|
class FasterCSV
|
84
84
|
# The version of the installed library.
|
85
|
-
VERSION = "1.5.
|
85
|
+
VERSION = "1.5.3".freeze
|
86
86
|
|
87
87
|
#
|
88
88
|
# A FasterCSV::Row is part Array and part Hash. It retains an order for the
|
@@ -704,8 +704,12 @@ class FasterCSV
|
|
704
704
|
# Returns the table as a complete CSV String. Headers will be listed first,
|
705
705
|
# then all of the field rows.
|
706
706
|
#
|
707
|
+
# This method assumes you want the Table.headers(), unless you explicitly
|
708
|
+
# pass <tt>:write_headers => false</tt>.
|
709
|
+
#
|
707
710
|
def to_csv(options = Hash.new)
|
708
|
-
|
711
|
+
wh = options.fetch(:write_headers, true)
|
712
|
+
@table.inject(wh ? [headers.to_csv(options)] : [ ]) do |rows, row|
|
709
713
|
if row.header_row?
|
710
714
|
rows
|
711
715
|
else
|
@@ -1576,10 +1580,10 @@ class FasterCSV
|
|
1576
1580
|
#
|
1577
1581
|
loop do
|
1578
1582
|
# add another read to the line
|
1579
|
-
|
1580
|
-
|
1581
|
-
|
1582
|
-
|
1583
|
+
if read_line = @io.gets(@row_sep)
|
1584
|
+
line += read_line
|
1585
|
+
else
|
1586
|
+
return nil
|
1583
1587
|
end
|
1584
1588
|
# copy the line so we can chop it up in parsing
|
1585
1589
|
parse = line.dup
|
@@ -1610,12 +1614,14 @@ class FasterCSV
|
|
1610
1614
|
parse.split(@col_sep, -1).each do |match|
|
1611
1615
|
if current_field.empty? && match.count(@quote_and_newlines).zero?
|
1612
1616
|
csv << (match.empty? ? nil : match)
|
1613
|
-
elsif(current_field.empty? ? match[0] : current_field[0]) ==
|
1617
|
+
elsif (current_field.empty? ? match[0] : current_field[0]) ==
|
1618
|
+
@quote_char[0]
|
1614
1619
|
current_field << match
|
1615
1620
|
field_quotes += match.count(@quote_char)
|
1616
1621
|
if field_quotes % 2 == 0
|
1617
1622
|
in_quotes = current_field[@parsers[:quoted_field], 1]
|
1618
|
-
raise MalformedCSVError
|
1623
|
+
raise MalformedCSVError if !in_quotes ||
|
1624
|
+
in_quotes[@parsers[:stray_quote]]
|
1619
1625
|
current_field = in_quotes
|
1620
1626
|
current_field.gsub!(@quote_char * 2, @quote_char) # unescape contents
|
1621
1627
|
csv << current_field
|
@@ -1793,14 +1799,17 @@ class FasterCSV
|
|
1793
1799
|
esc_row_sep = Regexp.escape(@row_sep)
|
1794
1800
|
esc_quote = Regexp.escape(@quote_char)
|
1795
1801
|
@parsers = {
|
1796
|
-
:any_field
|
1797
|
-
|
1798
|
-
|
1799
|
-
:quoted_field
|
1800
|
-
|
1801
|
-
|
1802
|
+
:any_field => Regexp.new( "[^#{esc_col_sep}]+",
|
1803
|
+
Regexp::MULTILINE,
|
1804
|
+
@encoding ),
|
1805
|
+
:quoted_field => Regexp.new( "^#{esc_quote}(.*)#{esc_quote}$",
|
1806
|
+
Regexp::MULTILINE,
|
1807
|
+
@encoding ),
|
1808
|
+
:stray_quote => Regexp.new( "[^#{esc_quote}]#{esc_quote}[^#{esc_quote}]",
|
1809
|
+
Regexp::MULTILINE,
|
1810
|
+
@encoding ),
|
1802
1811
|
# safer than chomp!()
|
1803
|
-
:line_end
|
1812
|
+
:line_end => Regexp.new("#{esc_row_sep}\\z", nil, @encoding)
|
1804
1813
|
}
|
1805
1814
|
end
|
1806
1815
|
|
data/test/tc_csv_parsing.rb
CHANGED
@@ -114,6 +114,10 @@ class TestCSVParsing < Test::Unit::TestCase
|
|
114
114
|
[["foo,\"foo,bar,baz,foo\",\"foo\"", ["foo", "foo,bar,baz,foo", "foo"]]].each do |edge_case|
|
115
115
|
assert_equal(edge_case.last, FasterCSV.parse_line(edge_case.first))
|
116
116
|
end
|
117
|
+
|
118
|
+
assert_raise(FasterCSV::MalformedCSVError) do
|
119
|
+
FasterCSV.parse_line("1,\"23\"4\"5\", 6")
|
120
|
+
end
|
117
121
|
end
|
118
122
|
|
119
123
|
def test_malformed_csv
|
data/test/tc_interface.rb
CHANGED
@@ -181,7 +181,7 @@ class TestFasterCSVInterface < Test::Unit::TestCase
|
|
181
181
|
csv << lines.first.keys
|
182
182
|
lines.each { |line| csv << line }
|
183
183
|
end
|
184
|
-
FasterCSV.open( @path, "
|
184
|
+
FasterCSV.open( @path, "r", :headers => true,
|
185
185
|
:converters => :all,
|
186
186
|
:header_converters => :symbol ) do |csv|
|
187
187
|
csv.each { |line| assert_equal(lines.shift, line.to_hash) }
|
data/test/tc_table.rb
CHANGED
@@ -251,6 +251,8 @@ class TestFasterCSVTable < Test::Unit::TestCase
|
|
251
251
|
# with options
|
252
252
|
assert_equal( csv.gsub(",", "|").gsub("\n", "\r\n"),
|
253
253
|
@table.to_csv(:col_sep => "|", :row_sep => "\r\n") )
|
254
|
+
assert_equal( csv.to_a[1..-1].join,
|
255
|
+
@table.to_csv(:write_headers => false) )
|
254
256
|
|
255
257
|
# with headers
|
256
258
|
assert_equal(csv, @header_table.to_csv)
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastercsv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 1
|
7
|
+
- 5
|
8
|
+
- 3
|
9
|
+
version: 1.5.3
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- James Edward Gray II
|
@@ -9,7 +14,7 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date: 2010-
|
17
|
+
date: 2010-03-16 00:00:00 -05:00
|
13
18
|
default_executable:
|
14
19
|
dependencies: []
|
15
20
|
|
@@ -80,18 +85,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
80
85
|
requirements:
|
81
86
|
- - ">="
|
82
87
|
- !ruby/object:Gem::Version
|
88
|
+
segments:
|
89
|
+
- 0
|
83
90
|
version: "0"
|
84
|
-
version:
|
85
91
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
92
|
requirements:
|
87
93
|
- - ">="
|
88
94
|
- !ruby/object:Gem::Version
|
95
|
+
segments:
|
96
|
+
- 0
|
89
97
|
version: "0"
|
90
|
-
version:
|
91
98
|
requirements: []
|
92
99
|
|
93
100
|
rubyforge_project: fastercsv
|
94
|
-
rubygems_version: 1.3.
|
101
|
+
rubygems_version: 1.3.6
|
95
102
|
signing_key:
|
96
103
|
specification_version: 3
|
97
104
|
summary: FasterCSV is CSV, but faster, smaller, and cleaner.
|