lib/roo/csv.rb in roo-1.11.2 vs lib/roo/csv.rb in roo-1.12.0
- old
+ new
@@ -1,52 +1,51 @@
require 'csv'
require 'time'
-# The Csv class can read csv files (must be separated with commas) which then
+# The CSV class can read csv files (must be separated with commas) which then
# can be handled like spreadsheets. This means you can access cells like A5
# within these files.
-# The Csv class provides only string objects. If you want conversions to other
+# The CSV class provides only string objects. If you want conversions to other
# types you have to do it yourself.
+#
+# You can pass options to the underlying CSV parse operation, via the
+# :csv_options option.
+#
-class Roo::Csv < Roo::GenericSpreadsheet
- def initialize(filename, packed=nil, file_warning=:error, tmpdir=nil)
- @filename = filename
- @cell = Hash.new
- @cell_type = Hash.new
- @cells_read = Hash.new
- @first_row = Hash.new
- @last_row = Hash.new
- @first_column = Hash.new
- @last_column = Hash.new
+class Roo::CSV < Roo::Base
+ def initialize(filename, options = {})
+ super
end
attr_reader :filename
- # Returns an array with the names of the sheets. In Csv class there is only
+ # Returns an array with the names of the sheets. In CSV class there is only
# one dummy sheet, because a csv file cannot have more than one sheet.
def sheets
['default']
end
def cell(row, col, sheet=nil)
sheet ||= @default_sheet
- read_cells(sheet) unless @cells_read[sheet]
- row,col = normalize(row,col)
- @cell[[row,col]]
+ read_cells(sheet)
+ @cell[normalize(row,col)]
end
def celltype(row, col, sheet=nil)
sheet ||= @default_sheet
- read_cells(sheet) unless @cells_read[sheet]
- row,col = normalize(row,col)
- @cell_type[[row,col]]
+ read_cells(sheet)
+ @cell_type[normalize(row,col)]
end
def cell_postprocessing(row,col,value)
value
end
+ def csv_options
+ @options[:csv_options] || {}
+ end
+
private
TYPE_MAP = {
String => :string,
Float => :float,
@@ -56,31 +55,30 @@
def celltype_class(value)
TYPE_MAP[value.class]
end
- def data
- @data ||=
+ def each_row(options, &block)
+ if uri?(filename)
make_tmpdir do |tmpdir|
- File.open(
- uri?(filename) ?
- open_from_uri(filename, tmpdir) :
- filename
- ) { |f| f.read }
+ filename = download_uri(filename, tmpdir)
+ CSV.foreach(filename, options, &block)
end
+ else
+ CSV.foreach(filename, options, &block)
+ end
end
def read_cells(sheet=nil)
sheet ||= @default_sheet
- @cell_type = {} unless @cell_type
- @cell = {} unless @cell
+ return if @cells_read[sheet]
@first_row[sheet] = 1
@last_row[sheet] = 0
@first_column[sheet] = 1
@last_column[sheet] = 1
rownum = 1
- CSV.parse data do |row|
+ each_row csv_options do |row|
row.each_with_index do |elem,i|
@cell[[rownum,i+1]] = cell_postprocessing rownum,i+1, elem
@cell_type[[rownum,i+1]] = celltype_class @cell[[rownum,i+1]]
if i+1 > @last_column[sheet]
@last_column[sheet] += 1
@@ -110,6 +108,6 @@
@last_column[sheet] and
@last_column[sheet] > @first_column[sheet]
@last_column[sheet] -= 1
end
end
-end # class Csv
+end