smarter_csv 1.1.5 → 1.12.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +5 -5
  2. data/.rspec +1 -2
  3. data/.rubocop.yml +154 -0
  4. data/CHANGELOG.md +364 -0
  5. data/CONTRIBUTORS.md +56 -0
  6. data/Gemfile +7 -2
  7. data/LICENSE.txt +21 -0
  8. data/README.md +44 -441
  9. data/Rakefile +39 -19
  10. data/TO_DO_v2.md +14 -0
  11. data/docs/_introduction.md +56 -0
  12. data/docs/basic_api.md +157 -0
  13. data/docs/batch_processing.md +68 -0
  14. data/docs/data_transformations.md +50 -0
  15. data/docs/examples.md +75 -0
  16. data/docs/header_transformations.md +113 -0
  17. data/docs/header_validations.md +36 -0
  18. data/docs/options.md +98 -0
  19. data/docs/row_col_sep.md +104 -0
  20. data/docs/value_converters.md +68 -0
  21. data/ext/smarter_csv/extconf.rb +14 -0
  22. data/ext/smarter_csv/smarter_csv.c +97 -0
  23. data/lib/smarter_csv/auto_detection.rb +78 -0
  24. data/lib/smarter_csv/errors.rb +16 -0
  25. data/lib/smarter_csv/file_io.rb +50 -0
  26. data/lib/smarter_csv/hash_transformations.rb +91 -0
  27. data/lib/smarter_csv/header_transformations.rb +63 -0
  28. data/lib/smarter_csv/header_validations.rb +34 -0
  29. data/lib/smarter_csv/headers.rb +68 -0
  30. data/lib/smarter_csv/options.rb +95 -0
  31. data/lib/smarter_csv/parser.rb +90 -0
  32. data/lib/smarter_csv/reader.rb +243 -0
  33. data/lib/smarter_csv/version.rb +3 -1
  34. data/lib/smarter_csv/writer.rb +116 -0
  35. data/lib/smarter_csv.rb +91 -3
  36. data/smarter_csv.gemspec +43 -20
  37. metadata +122 -137
  38. data/.gitignore +0 -8
  39. data/.travis.yml +0 -19
  40. data/lib/extensions/hash.rb +0 -7
  41. data/lib/smarter_csv/smarter_csv.rb +0 -281
  42. data/spec/fixtures/basic.csv +0 -8
  43. data/spec/fixtures/binary.csv +0 -1
  44. data/spec/fixtures/carriage_returns_n.csv +0 -18
  45. data/spec/fixtures/carriage_returns_quoted.csv +0 -3
  46. data/spec/fixtures/carriage_returns_r.csv +0 -1
  47. data/spec/fixtures/carriage_returns_rn.csv +0 -18
  48. data/spec/fixtures/chunk_cornercase.csv +0 -10
  49. data/spec/fixtures/empty.csv +0 -5
  50. data/spec/fixtures/line_endings_n.csv +0 -4
  51. data/spec/fixtures/line_endings_r.csv +0 -1
  52. data/spec/fixtures/line_endings_rn.csv +0 -4
  53. data/spec/fixtures/lots_of_columns.csv +0 -2
  54. data/spec/fixtures/malformed.csv +0 -3
  55. data/spec/fixtures/malformed_header.csv +0 -3
  56. data/spec/fixtures/money.csv +0 -3
  57. data/spec/fixtures/no_header.csv +0 -7
  58. data/spec/fixtures/numeric.csv +0 -5
  59. data/spec/fixtures/pets.csv +0 -5
  60. data/spec/fixtures/quoted.csv +0 -5
  61. data/spec/fixtures/separator.csv +0 -4
  62. data/spec/fixtures/skip_lines.csv +0 -8
  63. data/spec/fixtures/valid_unicode.csv +0 -5
  64. data/spec/fixtures/with_dashes.csv +0 -8
  65. data/spec/fixtures/with_dates.csv +0 -4
  66. data/spec/smarter_csv/binary_file2_spec.rb +0 -24
  67. data/spec/smarter_csv/binary_file_spec.rb +0 -22
  68. data/spec/smarter_csv/carriage_return_spec.rb +0 -170
  69. data/spec/smarter_csv/chunked_reading_spec.rb +0 -14
  70. data/spec/smarter_csv/close_file_spec.rb +0 -15
  71. data/spec/smarter_csv/column_separator_spec.rb +0 -11
  72. data/spec/smarter_csv/convert_values_to_numeric_spec.rb +0 -48
  73. data/spec/smarter_csv/extenstions_spec.rb +0 -17
  74. data/spec/smarter_csv/header_transformation_spec.rb +0 -21
  75. data/spec/smarter_csv/keep_headers_spec.rb +0 -24
  76. data/spec/smarter_csv/key_mapping_spec.rb +0 -25
  77. data/spec/smarter_csv/line_ending_spec.rb +0 -43
  78. data/spec/smarter_csv/load_basic_spec.rb +0 -20
  79. data/spec/smarter_csv/malformed_spec.rb +0 -21
  80. data/spec/smarter_csv/no_header_spec.rb +0 -24
  81. data/spec/smarter_csv/not_downcase_header_spec.rb +0 -24
  82. data/spec/smarter_csv/quoted_spec.rb +0 -23
  83. data/spec/smarter_csv/remove_empty_values_spec.rb +0 -13
  84. data/spec/smarter_csv/remove_keys_from_hashes_spec.rb +0 -25
  85. data/spec/smarter_csv/remove_not_mapped_keys_spec.rb +0 -35
  86. data/spec/smarter_csv/remove_values_matching_spec.rb +0 -26
  87. data/spec/smarter_csv/remove_zero_values_spec.rb +0 -25
  88. data/spec/smarter_csv/skip_lines_spec.rb +0 -29
  89. data/spec/smarter_csv/strings_as_keys_spec.rb +0 -24
  90. data/spec/smarter_csv/strip_chars_from_headers_spec.rb +0 -24
  91. data/spec/smarter_csv/valid_unicode_spec.rb +0 -94
  92. data/spec/smarter_csv/value_converters_spec.rb +0 -52
  93. data/spec/spec/spec_helper.rb +0 -17
  94. data/spec/spec.opts +0 -2
  95. data/spec/spec_helper.rb +0 -21
@@ -1,281 +0,0 @@
1
- module SmarterCSV
2
-
3
- class HeaderSizeMismatch < Exception; end
4
-
5
- class IncorrectOption < Exception; end
6
-
7
- def SmarterCSV.process(input, options={}, &block) # first parameter: filename or input object with readline method
8
- default_options = {:col_sep => ',' , :row_sep => $/ , :quote_char => '"', :force_simple_split => false , :verbose => false ,
9
- :remove_empty_values => true, :remove_zero_values => false , :remove_values_matching => nil , :remove_empty_hashes => true , :strip_whitespace => true,
10
- :convert_values_to_numeric => true, :strip_chars_from_headers => nil , :user_provided_headers => nil , :headers_in_file => true,
11
- :comment_regexp => /^#/, :chunk_size => nil , :key_mapping_hash => nil , :downcase_header => true, :strings_as_keys => false, :file_encoding => 'utf-8',
12
- :remove_unmapped_keys => false, :keep_original_headers => false, :value_converters => nil, :skip_lines => nil, :force_utf8 => false, :invalid_byte_sequence => '',
13
- :auto_row_sep_chars => 500
14
- }
15
- options = default_options.merge(options)
16
- options[:invalid_byte_sequence] = '' if options[:invalid_byte_sequence].nil?
17
- csv_options = options.select{|k,v| [:col_sep, :row_sep, :quote_char].include?(k)} # options.slice(:col_sep, :row_sep, :quote_char)
18
- headerA = []
19
- result = []
20
- old_row_sep = $/
21
- file_line_count = 0
22
- csv_line_count = 0
23
- begin
24
- f = input.respond_to?(:readline) ? input : File.open(input, "r:#{options[:file_encoding]}")
25
-
26
- if (options[:force_utf8] || options[:file_encoding] =~ /utf-8/i) && ( f.respond_to?(:external_encoding) && f.external_encoding != Encoding.find('UTF-8') || f.respond_to?(:encoding) && f.encoding != Encoding.find('UTF-8') )
27
- puts 'WARNING: you are trying to process UTF-8 input, but did not open the input with "b:utf-8" option. See README file "NOTES about File Encodings".'
28
- end
29
-
30
- if options[:row_sep] == :auto
31
- options[:row_sep] = line_ending = SmarterCSV.guess_line_ending( f, options )
32
- f.rewind
33
- end
34
- $/ = options[:row_sep]
35
-
36
- if options[:skip_lines].to_i > 0
37
- options[:skip_lines].to_i.times{f.readline}
38
- end
39
-
40
- if options[:headers_in_file] # extract the header line
41
- # process the header line in the CSV file..
42
- # the first line of a CSV file contains the header .. it might be commented out, so we need to read it anyhow
43
- header = f.readline
44
- header = header.force_encoding('utf-8').encode('utf-8', invalid: :replace, undef: :replace, replace: options[:invalid_byte_sequence]) if options[:force_utf8] || options[:file_encoding] !~ /utf-8/i
45
- header = header.sub(options[:comment_regexp],'').chomp(options[:row_sep])
46
-
47
- file_line_count += 1
48
- csv_line_count += 1
49
- header = header.gsub(options[:strip_chars_from_headers], '') if options[:strip_chars_from_headers]
50
-
51
- if (header =~ %r{#{options[:quote_char]}}) and (! options[:force_simple_split])
52
- file_headerA = begin
53
- CSV.parse( header, csv_options ).flatten.collect!{|x| x.nil? ? '' : x} # to deal with nil values from CSV.parse
54
- rescue CSV::MalformedCSVError => e
55
- raise $!, "#{$!} [SmarterCSV: csv line #{csv_line_count}]", $!.backtrace
56
- end
57
- else
58
- file_headerA = header.split(options[:col_sep])
59
- end
60
- file_headerA.map!{|x| x.gsub(%r/options[:quote_char]/,'') }
61
- file_headerA.map!{|x| x.strip} if options[:strip_whitespace]
62
- unless options[:keep_original_headers]
63
- file_headerA.map!{|x| x.gsub(/\s+|-+/,'_')}
64
- file_headerA.map!{|x| x.downcase } if options[:downcase_header]
65
- end
66
-
67
- file_header_size = file_headerA.size
68
- else
69
- raise SmarterCSV::IncorrectOption , "ERROR [smarter_csv]: If :headers_in_file is set to false, you have to provide :user_provided_headers" if options[:user_provided_headers].nil?
70
- end
71
- if options[:user_provided_headers] && options[:user_provided_headers].class == Array && ! options[:user_provided_headers].empty?
72
- # use user-provided headers
73
- headerA = options[:user_provided_headers]
74
- if defined?(file_header_size) && ! file_header_size.nil?
75
- if headerA.size != file_header_size
76
- raise SmarterCSV::HeaderSizeMismatch , "ERROR [smarter_csv]: :user_provided_headers defines #{headerA.size} headers != CSV-file #{input} has #{file_header_size} headers"
77
- else
78
- # we could print out the mapping of file_headerA to headerA here
79
- end
80
- end
81
- else
82
- headerA = file_headerA
83
- end
84
- headerA.map!{|x| x.to_sym } unless options[:strings_as_keys] || options[:keep_original_headers]
85
-
86
- unless options[:user_provided_headers] # wouldn't make sense to re-map user provided headers
87
- key_mappingH = options[:key_mapping]
88
-
89
- # do some key mapping on the keys in the file header
90
- # if you want to completely delete a key, then map it to nil or to ''
91
- if ! key_mappingH.nil? && key_mappingH.class == Hash && key_mappingH.keys.size > 0
92
- headerA.map!{|x| key_mappingH.has_key?(x) ? (key_mappingH[x].nil? ? nil : key_mappingH[x].to_sym) : (options[:remove_unmapped_keys] ? nil : x)}
93
- end
94
- end
95
-
96
- # in case we use chunking.. we'll need to set it up..
97
- if ! options[:chunk_size].nil? && options[:chunk_size].to_i > 0
98
- use_chunks = true
99
- chunk_size = options[:chunk_size].to_i
100
- chunk_count = 0
101
- chunk = []
102
- else
103
- use_chunks = false
104
- end
105
-
106
- # now on to processing all the rest of the lines in the CSV file:
107
- while ! f.eof? # we can't use f.readlines() here, because this would read the whole file into memory at once, and eof => true
108
- line = f.readline # read one line.. this uses the input_record_separator $/ which we set previously!
109
-
110
- # replace invalid byte sequence in UTF-8 with question mark to avoid errors
111
- line = line.force_encoding('utf-8').encode('utf-8', invalid: :replace, undef: :replace, replace: options[:invalid_byte_sequence]) if options[:force_utf8] || options[:file_encoding] !~ /utf-8/i
112
-
113
- file_line_count += 1
114
- csv_line_count += 1
115
- print "processing file line %10d, csv line %10d\r" % [file_line_count, csv_line_count] if options[:verbose]
116
- next if line =~ options[:comment_regexp] # ignore all comment lines if there are any
117
-
118
- # cater for the quoted csv data containing the row separator carriage return character
119
- # in which case the row data will be split across multiple lines (see the sample content in spec/fixtures/carriage_returns_rn.csv)
120
- # by detecting the existence of an uneven number of quote characters
121
- multiline = line.count(options[:quote_char])%2 == 1
122
- while line.count(options[:quote_char])%2 == 1
123
- next_line = f.readline
124
- next_line = next_line.force_encoding('utf-8').encode('utf-8', invalid: :replace, undef: :replace, replace: options[:invalid_byte_sequence]) if options[:force_utf8] || options[:file_encoding] !~ /utf-8/i
125
- line += next_line
126
- file_line_count += 1
127
- end
128
- print "\nline contains uneven number of quote chars so including content through file line %d\n" % file_line_count if options[:verbose] && multiline
129
-
130
- line.chomp! # will use $/ which is set to options[:col_sep]
131
-
132
- if (line =~ %r{#{options[:quote_char]}}) and (! options[:force_simple_split])
133
- dataA = begin
134
- CSV.parse( line, csv_options ).flatten.collect!{|x| x.nil? ? '' : x} # to deal with nil values from CSV.parse
135
- rescue CSV::MalformedCSVError => e
136
- raise $!, "#{$!} [SmarterCSV: csv line #{csv_line_count}]", $!.backtrace
137
- end
138
- else
139
- dataA = line.split(options[:col_sep])
140
- end
141
- dataA.map!{|x| x.gsub(%r/options[:quote_char]/,'') }
142
- dataA.map!{|x| x.strip} if options[:strip_whitespace]
143
- hash = Hash.zip(headerA,dataA) # from Facets of Ruby library
144
- # make sure we delete any key/value pairs from the hash, which the user wanted to delete:
145
- # Note: Ruby < 1.9 doesn't allow empty symbol literals!
146
- hash.delete(nil); hash.delete('');
147
- if RUBY_VERSION.to_f > 1.8
148
- eval('hash.delete(:"")')
149
- end
150
-
151
- # remove empty values using the same regexp as used by the rails blank? method
152
- # which caters for double \n and \r\n characters such as "1\r\n\r\n2" whereas the original check (v =~ /^\s*$/) does not
153
- hash.delete_if{|k,v| v.nil? || v !~ /[^[:space:]]/} if options[:remove_empty_values]
154
-
155
- hash.delete_if{|k,v| ! v.nil? && v =~ /^(\d+|\d+\.\d+)$/ && v.to_f == 0} if options[:remove_zero_values] # values are typically Strings!
156
- hash.delete_if{|k,v| v =~ options[:remove_values_matching]} if options[:remove_values_matching]
157
- if options[:convert_values_to_numeric]
158
- hash.each do |k,v|
159
- # deal with the :only / :except options to :convert_values_to_numeric
160
- next if SmarterCSV.only_or_except_limit_execution( options, :convert_values_to_numeric , k )
161
-
162
- # convert if it's a numeric value:
163
- case v
164
- when /^[+-]?\d+\.\d+$/
165
- hash[k] = v.to_f
166
- when /^[+-]?\d+$/
167
- hash[k] = v.to_i
168
- end
169
- end
170
- end
171
-
172
- if options[:value_converters]
173
- hash.each do |k,v|
174
- converter = options[:value_converters][k]
175
- next unless converter
176
- hash[k] = converter.convert(v)
177
- end
178
- end
179
-
180
- next if hash.empty? if options[:remove_empty_hashes]
181
-
182
- if use_chunks
183
- chunk << hash # append temp result to chunk
184
-
185
- if chunk.size >= chunk_size || f.eof? # if chunk if full, or EOF reached
186
- # do something with the chunk
187
- if block_given?
188
- yield chunk # do something with the hashes in the chunk in the block
189
- else
190
- result << chunk # not sure yet, why anybody would want to do this without a block
191
- end
192
- chunk_count += 1
193
- chunk = [] # initialize for next chunk of data
194
- else
195
-
196
- # the last chunk may contain partial data, which also needs to be returned (BUG / ISSUE-18)
197
-
198
- end
199
-
200
- # while a chunk is being filled up we don't need to do anything else here
201
-
202
- else # no chunk handling
203
- if block_given?
204
- yield [hash] # do something with the hash in the block (better to use chunking here)
205
- else
206
- result << hash
207
- end
208
- end
209
- end
210
-
211
- # print new line to retain last processing line message
212
- print "\n" if options[:verbose]
213
-
214
- # last chunk:
215
- if ! chunk.nil? && chunk.size > 0
216
- # do something with the chunk
217
- if block_given?
218
- yield chunk # do something with the hashes in the chunk in the block
219
- else
220
- result << chunk # not sure yet, why anybody would want to do this without a block
221
- end
222
- chunk_count += 1
223
- chunk = [] # initialize for next chunk of data
224
- end
225
- ensure
226
- $/ = old_row_sep # make sure this stupid global variable is always reset to it's previous value after we're done!
227
- f.close
228
- end
229
- if block_given?
230
- return chunk_count # when we do processing through a block we only care how many chunks we processed
231
- else
232
- return result # returns either an Array of Hashes, or an Array of Arrays of Hashes (if in chunked mode)
233
- end
234
- end
235
-
236
- private
237
- # acts as a road-block to limit processing when iterating over all k/v pairs of a CSV-hash:
238
-
239
- def self.only_or_except_limit_execution( options, option_name, key )
240
- if options[option_name].is_a?(Hash)
241
- if options[option_name].has_key?( :except )
242
- return true if Array( options[ option_name ][:except] ).include?(key)
243
- elsif options[ option_name ].has_key?(:only)
244
- return true unless Array( options[ option_name ][:only] ).include?(key)
245
- end
246
- end
247
- return false
248
- end
249
-
250
- # limitation: this currently reads the whole file in before making a decision
251
- def self.guess_line_ending( filehandle, options )
252
- counts = {"\n" => 0 , "\r" => 0, "\r\n" => 0}
253
- quoted_char = false
254
-
255
- # count how many of the pre-defined line-endings we find
256
- # ignoring those contained within quote characters
257
- last_char = nil
258
- lines = 0
259
- filehandle.each_char do |c|
260
- quoted_char = !quoted_char if c == options[:quote_char]
261
- next if quoted_char
262
-
263
- if last_char == "\r"
264
- if c == "\n"
265
- counts["\r\n"] += 1
266
- else
267
- counts["\r"] += 1 # \r are counted after they appeared, we might
268
- end
269
- elsif c == "\n"
270
- counts["\n"] += 1
271
- end
272
- last_char = c
273
- lines += 1
274
- break if options[:auto_row_sep_chars] && options[:auto_row_sep_chars] > 0 && lines >= options[:auto_row_sep_chars]
275
- end
276
- counts["\r"] += 1 if last_char == "\r"
277
- # find the key/value pair with the largest counter:
278
- k,_ = counts.max_by{|_,v| v}
279
- return k # the most frequent one is it
280
- end
281
- end
@@ -1,8 +0,0 @@
1
- First Name,Last Name,Dogs,Cats,Birds,Fish
2
- Dan,McAllister,2,0,,
3
- Lucy,Laweless,,5,0,
4
- ,,,,,
5
- Miles,O'Brian,0,0,0,21
6
- Nancy,Homes,2,0,1,
7
- Hernán,Curaçon,3,0,0,
8
- ,,,,,
@@ -1 +0,0 @@
1
- #timestampitem_idparent_idname#some comments here#these can be multiple comments in the header section#even more comments here1381388409101Thing 11381388409111Thing 21381388409121Thing 313813884091Parent 113813884092Parent 21381388409202Thing 41381388409212Thing 51381388409222Thing 6
@@ -1,18 +0,0 @@
1
- Name,Street,City
2
- Anfield,Anfield Road,Liverpool
3
- "Highbury
4
- Highbury House",75 Drayton Park,London
5
- Old Trafford,"Sir Matt
6
- Busby Way",Manchester
7
- St. James' Park,,"Newcastle-upon-tyne
8
- Tyne and Wear"
9
- "White Hart Lane
10
- (The Lane)","Bill Nicholson Way
11
- 748 High Rd","Tottenham
12
- London"
13
- Stamford Bridge,"Fulham Road
14
- London",
15
- "Etihad Stadium
16
- Rowsley St
17
- Manchester",,
18
- Goodison,Goodison Road,Liverpool
@@ -1,3 +0,0 @@
1
- Band,Members,Albums
2
- New Order,"Bernard Sumner
3
- Led Zeppelin,"Jimmy Page
@@ -1 +0,0 @@
1
- Name,Street,City
@@ -1,18 +0,0 @@
1
- Name,Street,City
2
- Anfield,Anfield Road,Liverpool
3
- "Highbury
4
- Highbury House",75 Drayton Park,London
5
- Old Trafford,"Sir Matt
6
- Busby Way",Manchester
7
- St. James' Park,,"Newcastle-upon-tyne
8
- Tyne and Wear"
9
- "White Hart Lane
10
- (The Lane)","Bill Nicholson Way
11
- 748 High Rd","Tottenham
12
- London"
13
- Stamford Bridge,"Fulham Road
14
- London",
15
- "Etihad Stadium
16
- Rowsley St
17
- Manchester",,
18
- Goodison,Goodison Road,Liverpool
@@ -1,10 +0,0 @@
1
- a,b,c
2
- 1,2,3
3
- ,,
4
- 4,5,6
5
- 7,8,9
6
- ,,
7
- 10,11,12
8
- ,,
9
- 13,14,15
10
- ,,
@@ -1,5 +0,0 @@
1
- not empty 1,not empty 2,not empty 3,empty 1,empty 2
2
- 56
3
-
4
- 666
5
- ",?,"
@@ -1,4 +0,0 @@
1
- name,count,price
2
- hammer,4,12.50
3
- axe,2,7.30
4
- crowbar,3,17.50
@@ -1 +0,0 @@
1
- name,count,price
@@ -1,4 +0,0 @@
1
- name,count,price
2
- hammer,4,12.50
3
- axe,2,7.30
4
- crowbar,3,17.50
@@ -1,2 +0,0 @@
1
- Column 0,Column 1,Column 2,Column 3,Column 4,Column 5,Column 6,Column 7,Column 8,Column 9,Column 10,Column 11,Column 12,Column 13,Column 14,Column 15,Column 16,Column 17,Column 18,Column 19,Column 20,Column 21,Column 22,Column 23,Column 24,Column 25,Column 26,Column 27,Column 28,Column 29,Column 30,Column 31,Column 32,Column 33,Column 34,Column 35,Column 36,Column 37,Column 38,Column 39,Column 40,Column 41,Column 42,Column 43,Column 44,Column 45,Column 46,Column 47,Column 48,Column 49,Column 50,Column 51,Column 52,Column 53,Column 54,Column 55,Column 56,Column 57,Column 58,Column 59,Column 60,Column 61,Column 62,Column 63,Column 64,Column 65,Column 66,Column 67,Column 68,Column 69,Column 70,Column 71,Column 72,Column 73,Column 74,Column 75,Column 76,Column 77,Column 78,Column 79,Column 80,Column 81,Column 82,Column 83,Column 84,Column 85,Column 86,Column 87,Column 88,Column 89,Column 90,Column 91,Column 92,Column 93,Column 94,Column 95,Column 96,Column 97,Column 98,Column 99,Column 100,Column 101,Column 102,Column 103,Column 104,Column 105,Column 106,Column 107,Column 108,Column 109,Column 110,Column 111,Column 112,Column 113,Column 114,Column 115,Column 116,Column 117,Column 118,Column 119,Column 120,Column 121,Column 122,Column 123,Column 124,Column 125,Column 126,Column 127,Column 128,Column 129,Column 130,Column 131,Column 132,Column 133,Column 134,Column 135,Column 136,Column 137,Column 138,Column 139,Column 140,Column 141,Column 142,Column 143,Column 144,Column 145,Column 146,Column 147,Column 148,Column 149,Column 150,Column 151,Column 152,Column 153,Column 154,Column 155,Column 156,Column 157,Column 158,Column 159,Column 160,Column 161,Column 162,Column 163,Column 164,Column 165,Column 166,Column 167,Column 168,Column 169,Column 170,Column 171,Column 172,Column 173,Column 174,Column 175,Column 176,Column 177,Column 178,Column 179,Column 180,Column 181,Column 182,Column 183,Column 184,Column 185,Column 186,Column 187,Column 188,Column 189,Column 190,Column 191,Column 192,Column 193,Column 194,Column 195,Column 196,Column 197,Column 198,Column 199,Column 200,Column 201,Column 202,Column 203,Column 204,Column 205,Column 206,Column 207,Column 208,Column 209,Column 210,Column 211,Column 212,Column 213,Column 214,Column 215,Column 216,Column 217,Column 218,Column 219,Column 220,Column 221,Column 222,Column 223,Column 224,Column 225,Column 226,Column 227,Column 228,Column 229,Column 230,Column 231,Column 232,Column 233,Column 234,Column 235,Column 236,Column 237,Column 238,Column 239,Column 240,Column 241,Column 242,Column 243,Column 244,Column 245,Column 246,Column 247,Column 248,Column 249,Column 250,Column 251,Column 252,Column 253,Column 254,Column 255,Column 256,Column 257,Column 258,Column 259,Column 260,Column 261,Column 262,Column 263,Column 264,Column 265,Column 266,Column 267,Column 268,Column 269,Column 270,Column 271,Column 272,Column 273,Column 274,Column 275,Column 276,Column 277,Column 278,Column 279,Column 280,Column 281,Column 282,Column 283,Column 284,Column 285,Column 286,Column 287,Column 288,Column 289,Column 290,Column 291,Column 292,Column 293,Column 294,Column 295,Column 296,Column 297,Column 298,Column 299,Column 300,Column 301,Column 302,Column 303,Column 304,Column 305,Column 306,Column 307,Column 308,Column 309,Column 310,Column 311,Column 312,Column 313,Column 314,Column 315,Column 316,Column 317,Column 318,Column 319,Column 320,Column 321,Column 322,Column 323,Column 324,Column 325,Column 326,Column 327,Column 328,Column 329,Column 330,Column 331,Column 332,Column 333,Column 334,Column 335,Column 336,Column 337,Column 338,Column 339,Column 340,Column 341,Column 342,Column 343,Column 344,Column 345,Column 346,Column 347,Column 348,Column 349,Column 350,Column 351,Column 352,Column 353,Column 354,Column 355,Column 356,Column 357,Column 358,Column 359,Column 360,Column 361,Column 362,Column 363,Column 364,Column 365,Column 366,Column 367,Column 368,Column 369,Column 370,Column 371,Column 372,Column 373,Column 374,Column 375,Column 376,Column 377,Column 378,Column 379,Column 380,Column 381,Column 382,Column 383,Column 384,Column 385,Column 386,Column 387,Column 388,Column 389,Column 390,Column 391,Column 392,Column 393,Column 394,Column 395,Column 396,Column 397,Column 398,Column 399,Column 400,Column 401,Column 402,Column 403,Column 404,Column 405,Column 406,Column 407,Column 408,Column 409,Column 410,Column 411,Column 412,Column 413,Column 414,Column 415,Column 416,Column 417,Column 418,Column 419,Column 420,Column 421,Column 422,Column 423,Column 424,Column 425,Column 426,Column 427,Column 428,Column 429,Column 430,Column 431,Column 432,Column 433,Column 434,Column 435,Column 436,Column 437,Column 438,Column 439,Column 440,Column 441,Column 442,Column 443,Column 444,Column 445,Column 446,Column 447,Column 448,Column 449,Column 450,Column 451,Column 452,Column 453,Column 454,Column 455,Column 456,Column 457,Column 458,Column 459,Column 460,Column 461,Column 462,Column 463,Column 464,Column 465,Column 466,Column 467,Column 468,Column 469,Column 470,Column 471,Column 472,Column 473,Column 474,Column 475,Column 476,Column 477,Column 478,Column 479,Column 480,Column 481,Column 482,Column 483,Column 484,Column 485,Column 486,Column 487,Column 488,Column 489,Column 490,Column 491,Column 492,Column 493,Column 494,Column 495,Column 496,Column 497,Column 498,Column 499
2
- rFDAsZLKkINpb,ChLVlxWpwZfrOZg,uGJbxzrFncG,R,P,j,QoKRekBnucMA,N,KJFTwrG,Fs,pKazVnOVFnLvAcK,bo,EgJwvAwnGYPdvj,qVPGxupPKQI,FtNJBxxMIBxezfS,,qrcOm,Angkc,kwhJvozx,H,Yk,Bs,JZTVzstyk,sDiZuoBOVPA,hsgzXcqSnUaF,,AMQcprcuLABRvLF,NxwQvVApPdtTJSw,tKjftA,lOyqAtUuXQtK,ImgNiMBPRo,dyVW,dVbtwSuZuX,IQN,pUEEshP,QVKcImQ,HDoRZ,jrQpVdvtjGHv,YkP,dHyjESzVsgUdRh,p,qz,oCP,clMCAiuiw,JzxVq,zpn,bwfoYmrJkTc,t,HGYcQdMmNjb,CFFbJTeOozA,,MwroljZZwEoBOoc,,wkIRXssJZ,LSaIDarn,qky,BDMJVYE,thOpnBTTiGMfa,JVhoOwTdoukH,xIECafnWcE,,,kbxzc,viKcs,dwVMljnI,fYXJYw,PhohmrDa,alGbl,aeqwrXgjr,MJ,gapeNlzKYUP,tys,PJPfxFYYFPclGJV,HIUXf,AjmDljNZjYqB,HbxoDVzzkQ,aLQFk,PormYxT,rATMrIlCFrDwOzD,Krv,pMwcHztVfVkKo,srb,fdlXgWtPK,r,UZvVNkLYigVzZO,RPDHskEaMqq,dVkUXNKFRbwq,FGSqF,mqG,aZzufH,LHsN,NkKlcjoRFTbFH,ChEHvIQDYomC,L,URFkXirNgU,M,gAtCyH,FLkbLzwEBLgtlt,OadGQgGxGqGkT,tEQUWJDpb,p,fXIyPxIftbgHNPL,dM,mrz,cGXxRFLUG,MMvNyk,mKEcw,QMROkjgOWnBSZI,DQQ,QeKZt,Xaor,KUPKflOhGnrOMu,VpwHZUN,raDbObrwsRaa,,WqddHDTh,wj,XZtQIS,CGPUgYOQtiu,,zRkl,,ATlS,JheeokutCEtvAdV,hozEKLGRET,DsEiWDjQ,lTQjDhEah,WqREQoJLBSP,,FOaImBDZclTMM,vhEjpJddIVh,xC,ZCSpDtdJw,phRxoGO,VdhVyRebsNynrk,HfCkVLQnLnRLA,dwxQUCPZc,koFg,lumNQmIweYyTc,R,bDRcfIO,cxH,n,navCHjPdfj,puDQpjuIIMRDqK,EVkAd,ARVpVku,hUEqyejzKt,,Qtygnqk,HlZgSRnbmIHZP,QZpVTn,OQgoIZhxIsh,TYPUMV,ofjg,YvYMWpSOAA,PGtCCHInmFBqPp,va,viWLIIjBOEwQCP,E,yjKVemUmGC,FQhSaVdeAJjO,flcBAZzLOlrg,bShmRGHdOemzMZi,gjUzxDONxWymoK,ZS,VBFVHug,igVYBKUJIcGKbim,msrUQUHTNymL,,pVeEHwNN,BqnU,UkYsIhEnqayMIa,RQHqYCoEU,ujuLHy,DctKlTNlADp,MJmfaBxeNIONUTQ,BcPqmfBSWJEs,kH,bYQiLOweBh,ajEmwTPgdGtDI,aeMJiQthn,QfvLiAuJjYB,aNauvl,bcCqdQie,tCwTqF,tNVw,sbjLwbktZUM,Mkrlh,sQihM,clRevuPt,weuxLMDulNP,juaeGRXAz,SKenpQsEZqAA,UGdQdLHvOH,brBHqPjs,WLS,fZ,DBSBUMvgLYzbKH,eFks,zLt,hqnDnIsUsremb,dizzYLAKUGXsH,vDWNIbiepsMPPm,QHNpZgZ,vl,KpukrVVjLDll,rbOPLzI,woALqQUQnt,JiG,SGZGCjPyvceLmy,ofcCQgXjgVmRsxV,,EERhEDO,PxuJxrOka,ohMLIz,vpUnwsJejGkurJ,ISjplKfjrYLE,jZgXFIcRDQQkcI,XfKGtVsclDH,UtKeOSPhbf,,AtWJyGatftYCiA,pzEJCjFA,beuwjh,OrrcIHW,SjuBT,xVNUQEjxyB,CTDOUCAxhx,YpCApsrXvk,Gp,Us,ALBNnNFhdbMYjpl,msB,XniwYCr,aMImLpFlzbz,p,guQBgEARv,NRwcXFoVyjuRi,QfLRUsEQq,WrzdF,QVb,oDTGOMYEVu,iAfcPl,wLkI,VON,,P,TPwCynToFkJI,gZzcqx,QrZNqo,p,WSfbj,ldxi,taws,meZ,g,icjnchZcQQIqrnQ,RQRmriLCPE,Lxnxu,AoC,XNbQ,GhQqR,GSHHsytQGKNLJGU,PBi,IjIszY,WfXyRMqGBkI,jL,loeFjtFErHKhPv,YHAubVlaujA,hNAbVNu,sLhChzeLLvYXR,DnL,hamyOyGAouk,cNOZnSPNhoFjAFq,RXOFzh,JkgdgUCEI,ZidLIxtn,KaMuBFTdvSSN,Owj,dSHiNUxjaGQcieG,rVSK,DwxWsgHgbeiIVoF,I,NsOEAk,Hqdv,Xeedwold,aVFPYNWIehmpgZ,gH,yl,GDesAPfYPtrkDEx,YZbPYzQBUaseUBi,FYSJAlciOmnK,DjRdbezjrAdQcX,FUNKjgklfnksvn,NMCfDtqFvcI,T,rpkwYAmR,nTAJTyiVPbFuv,qKdFCrPCEPRE,xATVXeqsAKRcYV,tHzCGeqnplni,cXGiZMgXct,souXHmYybMmbyhg,i,oDhWt,L,kwesSP,jyksdMdyne,TCyYt,wX,JiSsPdDajKirPgL,cc,qnCQz,TS,luVvIgALvyB,,eGpRJq,RKWwtfwHo,ISEH,SiRldWBiF,jyFuxIz,cVojag,FGWd,HF,xI,xOwUyr,iDDEDH,vyDxjfVus,zLvpx,ssrFvXDVo,kXEzRcW,opsKOmCLbFwSM,xHfeHRWwalx,n,KOrSY,CAOTgyQJm,wCuuuzwffVEY,ldmjKUum,EDQzj,czqFC,GYAKCxOiu,nAM,uNQnVaBCj,TvoVlpJWYI,SFlUDJ,XTuQjsZtpUhgWId,D,xEiowDk,PaBftY,,PNdZMqagJawiLKy,pUcrcOEKSP,RlDCo,,kcK,RJugqQIBYfhC,W,ov,PzfdKIR,OBIa,JYXxqRucy,UaTDgAkJfw,,ydlnbzoww,fQdyIegvIc,DlT,LSqWLh,ihm,sR,MInOCbVexl,NuwJxdxvkTXa,nlJrPpKDIf,iWOwycGEID,PQdoTHebXj,DROZTCRnma,cFAMtx,BkYpK,JitcTdIPlTMEfl,wOSBOJEnIOw,CeEItVPQEeIfFgZ,OiCeEuVRKJ,hjFaJxsTYRCgFYz,giSKHpCNXNk,RaNmFDao,htRSneNtuDta,HdRaC,vkIkWSGebQbpaT,kzyJVn,gMMGxfRjFskmoo,xtfUXOdrlUs,CoSIbIPfVfTXko,zVOXIJ,UGQIlWuRzDJAPsn,,sWXjt,dNkgPEgim,WVmBPZSTa,KJnedQffhg,e,XhgwuoHiR,rt,FYNI,Rk,ImHT,QXR,Ta,wvU,qhsGIux,yyrLPMQmKVkCp,SBYM,a,aCxwZKlj,,lcNXLvIEkjQTO,XjpXtlM,PhdrxqxDVWO,pCIQtTuwu,WAbZHWAEtzLJOql,XDETKm,KuF,PozCBInp,d,tWtj,QKjx,eFevbQsOtGGxJM,FZIvXPnOKDMDgdB,khe,YdnPTMxczkm,L,SREiJirL,irZJxq,vl,SYsHw,vKSe,ypvRthKFyTRs,IuAdRz,lGotaaKUU,hxMTxzrUFT,dFCbGN,WDTco,xXhedTTXbbDllWX,M,MrhdNyXzFxP,LjX,qRqvrGrNzC,E,nQ,gOWQSgeCwVIq,ASGxcPYYmTAVm,gbnOqDOicyz,h,gviqOP,oV,QjDOngDXFeYp,ojPwZPSodxzxbu,jcWTp,ERHZmFboGYVCQxP,ox,PsFrmpSe,GbhohxlLVcU,rKMLpQNsvH,UzMJMaK,GilkAEVQWzUA,PGCrmxvKB,jOEDmSM,arTAqyNOUtsWj,,,sQXstIGqFfJg,FYOsFdUYr,DwYhqnBlsGtfez,FcKkwqG,sqZFwfyPByL,RkB,tYVdRtbHpdTRPBf,kObsAtqgghqe,,awzrSqHxz,,aXarXMPnQJgqJyM,ldb,NOdwJ,gUYvxxVPCcrmDOd,dcNR,,uglxXybrDyaHCU,JYRLQC,SoolzzZaZ,OZXZiMSimJrH,iZQiZl,bIDq,OSd,UopfHT,f,v,ynUYQwMmKrH,MtF,Cn,ad
@@ -1,3 +0,0 @@
1
- "name","dob"
2
- "Arnold Schwarzenegger","1947-07-30"
3
- "Jeff "the dude" Bridges","1949-12-04"
@@ -1,3 +0,0 @@
1
- "name","dob"dob""
2
- "Arnold Schwarzenegger","1947-07-30"
3
- "Jeff Bridges","1949-12-04"
@@ -1,3 +0,0 @@
1
- item,price
2
- Book,$9.99
3
- Mug,$14.99
@@ -1,7 +0,0 @@
1
- Dan,McAllister,2,0,,
2
- Lucy,Laweless,,5,0,
3
- ,,,,,
4
- Miles,O'Brian,0,0,0,21
5
- Nancy,Homes,2,0,1,
6
- Hernán,Curaçon,3,0,0,
7
- ,,,,,
@@ -1,5 +0,0 @@
1
- First Name,Last Name,Reference, Wealth
2
- Dan,McAllister,0123,3.5
3
- ,,,,,
4
- Miles,O'Brian,2345,3
5
- Nancy,Homes,2345,01
@@ -1,5 +0,0 @@
1
- first name,last name,dogs,cats,birds,fish
2
- Dan,McAllister,2,,,
3
- Lucy,Laweless,,5,,
4
- Miles,O'Brian,,,,21
5
- Nancy,Homes,2,,1,
@@ -1,5 +0,0 @@
1
- Year,Make,Model,Description,Price
2
- 1997,Ford,E350,"ac, abs, moon",3000.00
3
- 1999,Chevy,"Venture ""Extended Edition""","",4900.00
4
- 1999,Chevy,"Venture ""Extended Edition, Very Large""",,5000.00
5
- 1996,Jeep,Grand Cherokee,"MUST SELL! air, moon roof, loaded",4799.00
@@ -1,4 +0,0 @@
1
- Year;Make;Model;Length
2
- 1997;Ford;E350;2,34
3
- 2000;Mercury;Cougar;2,38
4
- 2013;Tesla;Model S;4,97
@@ -1,8 +0,0 @@
1
- Lines
2
- To
3
- Skip
4
- first name,last name,dogs,cats,birds,fish
5
- Dan,McAllister,2,,,
6
- Lucy,Laweless,,5,,
7
- Miles,O'Brian,,,,21
8
- Nancy,Homes,2,,1,
@@ -1,5 +0,0 @@
1
- "Artist","Track","Album","Label","Year"
2
- Кино,"Мама, мы все сошли с ума",Группа Крови,Moroz Records,1998
3
- "Кино","Мама, мы все сошли с ума","Группа Крови","Moroz Records",1998
4
- Rammstein,Frühling in Paris,Liebe ist für alle da,Vagrant,2009
5
- "Rammstein","Frühling in Paris","Liebe ist für alle da","Vagrant",2009
@@ -1,8 +0,0 @@
1
- First-Name,Last-Name,Dogs,Cats,Birds,Fish
2
- Dan,McAllister,2,0,,
3
- Lucy,Laweless,,5,0,
4
- ,,,,,
5
- Miles,O'Brian,0,0,0,21
6
- Nancy,Homes,2,0,1,
7
- Hernán,Curaçon,3,0,0,
8
- ,,,,,
@@ -1,4 +0,0 @@
1
- first,last,date,price
2
- Ben,Miller,10/30/1998,$44.50
3
- Tom,Turner,2/1/2011,$15
4
- Ken,Smith,01/09/2013,$0.11
@@ -1,24 +0,0 @@
1
- require 'spec_helper'
2
-
3
- fixture_path = 'spec/fixtures'
4
-
5
- # this reads a binary database dump file, which is in structure like a CSV file
6
- # but contains control characters delimiting the rows and columns, and also
7
- # contains a comment section which is commented our by a leading # character
8
-
9
- # same as binary_file_spec , but reading the file with strings as keys
10
-
11
- describe 'be_able_to' do
12
- it 'loads_binary_file_with_strings_as_keys' do
13
- options = {:col_sep => "\cA", :row_sep => "\cB", :comment_regexp => /^#/, :strings_as_keys => true}
14
- data = SmarterCSV.process("#{fixture_path}/binary.csv", options)
15
- data.flatten.size.should == 8
16
- data.each do |item|
17
- # all keys should be strings
18
- item.keys.each{|x| x.class.should be == String}
19
- item['timestamp'].should == 1381388409
20
- item['item_id'].class.should be == Fixnum
21
- item['name'].size.should be > 0
22
- end
23
- end
24
- end
@@ -1,22 +0,0 @@
1
- require 'spec_helper'
2
-
3
- fixture_path = 'spec/fixtures'
4
-
5
- # this reads a binary database dump file, which is in structure like a CSV file
6
- # but contains control characters delimiting the rows and columns, and also
7
- # contains a comment section which is commented our by a leading # character
8
-
9
- describe 'be_able_to' do
10
- it 'loads_binary_file_with_comments' do
11
- options = {:col_sep => "\cA", :row_sep => "\cB", :comment_regexp => /^#/}
12
- data = SmarterCSV.process("#{fixture_path}/binary.csv", options)
13
- data.flatten.size.should == 8
14
- data.each do |item|
15
- # all keys should be symbols
16
- item.keys.each{|x| x.class.should be == Symbol}
17
- item[:timestamp].should == 1381388409
18
- item[:item_id].class.should be == Fixnum
19
- item[:name].size.should be > 0
20
- end
21
- end
22
- end