csv_madness 0.0.9 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of csv_madness might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.document +5 -0
- data/CHANGELOG.markdown +4 -0
- data/Gemfile +2 -7
- data/Rakefile +12 -78
- data/VERSION +1 -1
- data/lib/csv_madness/builder.rb +91 -9
- data/lib/csv_madness/column.rb +30 -0
- data/lib/csv_madness/column_methods/core_methods.rb +6 -0
- data/lib/csv_madness/column_methods/default_value_methods.rb +7 -0
- data/lib/csv_madness/column_methods/error_methods.rb +19 -0
- data/lib/csv_madness/column_methods/fetch_methods.rb +11 -0
- data/lib/csv_madness/column_methods/typing_methods.rb +24 -0
- data/lib/csv_madness/column_set.rb +5 -0
- data/lib/csv_madness/column_type.rb +74 -0
- data/lib/csv_madness/column_types/date.rb +14 -0
- data/lib/csv_madness/column_types/float.rb +25 -0
- data/lib/csv_madness/column_types/integer.rb +17 -0
- data/lib/csv_madness/column_types/string.rb +9 -0
- data/lib/csv_madness/data_accessor_module.rb +79 -79
- data/lib/csv_madness/gem_api.rb +11 -2
- data/lib/csv_madness/index_set.rb +36 -0
- data/lib/csv_madness/indexer.rb +105 -0
- data/lib/csv_madness/record.rb +68 -42
- data/lib/csv_madness/record_filter.rb +68 -0
- data/lib/csv_madness/record_methods/method_methods.rb +57 -0
- data/lib/csv_madness/sheet.rb +160 -76
- data/lib/csv_madness/sheet_methods/class_methods.rb +11 -4
- data/lib/csv_madness/sheet_methods/column_methods.rb +95 -107
- data/lib/csv_madness/sheet_methods/file_methods.rb +9 -6
- data/lib/csv_madness/sheet_methods/indexing.rb +104 -23
- data/lib/csv_madness/sheet_methods/record_methods.rb +123 -47
- data/lib/csv_madness/sheet_methods/sorting_methods.rb +10 -0
- data/lib/csv_madness/utils/const_proc.rb +19 -0
- data/lib/csv_madness/utils/counter.rb +24 -0
- data/lib/csv_madness/utils/counter_proc.rb +31 -0
- data/lib/csv_madness/utils/looker_upper.rb +36 -0
- data/lib/csv_madness.rb +1 -0
- data/test/csv/nil_headers.csv +5 -0
- data/test/csv/out/.gitkeep +0 -0
- data/test/csv/pokemon.csv +9 -0
- data/test/csv/test_column_types.csv +2 -2
- data/test/helper.rb +9 -6
- data/test/test_builder.rb +36 -0
- data/test/test_csv_madness.rb +28 -18
- data/test/test_index_set.rb +30 -0
- data/test/test_indexer.rb +50 -0
- data/test/test_reloading_spreadsheet.rb +4 -2
- data/test/test_sheet.rb +164 -27
- data/test/test_utils.rb +99 -0
- metadata +66 -38
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 63380347571236804849e35c32c5463efc6e71151e992a3e3f18f8d2673fc110
|
|
4
|
+
data.tar.gz: 8c58382266af7f1091a80dc89eb6900a4efb8a5f956fe5801aa77ea5d5e4f05f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3b8ca366e680bf629fbb081145a8b254e5a121102b0772a40095893e06bc1f46f1f081c64cfa60efb1cbe69e633685c65b406795601c237157a8af63a5ce4d3c
|
|
7
|
+
data.tar.gz: 298b6b68d6bed7254ae7177b6fd24f8bfccb765435df5fbd5e9bfabb618db3bf386c276c741ca5fbab2bd9d8168c011010579ccca3bbfe7af0a19a2cffe163ad
|
data/.document
ADDED
data/CHANGELOG.markdown
CHANGED
data/Gemfile
CHANGED
|
@@ -7,13 +7,8 @@ source "http://rubygems.org"
|
|
|
7
7
|
# Include everything needed to run rake, tests, features, etc.
|
|
8
8
|
|
|
9
9
|
group :development do
|
|
10
|
-
# gem "shoulda", ">= 3.5"
|
|
11
|
-
# gem "rdoc", "~> 3.12"
|
|
12
|
-
# gem "bundler", "~> 1.5"
|
|
13
|
-
# gem "jeweler", "~> 2"
|
|
14
10
|
gem "fun_with_testing"
|
|
15
|
-
# gem "debugger"
|
|
16
11
|
end
|
|
17
12
|
|
|
18
|
-
gem "
|
|
19
|
-
gem '
|
|
13
|
+
gem 'fun_with_gems', '~> 0.0', ">= 0.0.6"
|
|
14
|
+
gem 'csv' # removed from core
|
data/Rakefile
CHANGED
|
@@ -1,89 +1,23 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
require 'fun_with_gems'
|
|
3
3
|
require_relative File.join( "lib", "csv_madness" )
|
|
4
|
-
self.extend( FunWith::Gems::Rakefile)
|
|
5
4
|
|
|
5
|
+
self.extend( FunWith::Gems::Rakefile )
|
|
6
6
|
rakefile_setup CsvMadness
|
|
7
7
|
|
|
8
8
|
gem_specification do |gem|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
9
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
|
10
|
+
# dependencies defined in Gemfile
|
|
11
|
+
gem.name = "csv_madness"
|
|
12
|
+
gem.homepage = "http://github.com/darthschmoo/csv_madness"
|
|
13
|
+
gem.license = "MIT"
|
|
14
|
+
gem.summary = "CSV Madness turns your CSV rows into happycrazy objects."
|
|
15
|
+
gem.description = "CSV Madness removes what little pain is left from Ruby's CSV class. Load a CSV file, and get back an array of objects with customizable getter/setter methods."
|
|
16
|
+
gem.email = "keeputahweird@gmail.com"
|
|
17
|
+
gem.authors = ["Bryce Anderson"]
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Dir.glob( File.join( ".", "test", "**", "*" ) ) +
|
|
22
|
-
%w( Gemfile Rakefile LICENSE.txt README.rdoc VERSION CHANGELOG.markdown )
|
|
23
|
-
# csv_madness.gemspec )
|
|
19
|
+
# dependencies defined in Gemfile
|
|
20
|
+
add_specification_files( gem, :default )
|
|
24
21
|
end
|
|
25
22
|
|
|
26
23
|
setup_gem_boilerplate
|
|
27
|
-
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
# require 'rubygems'
|
|
31
|
-
# require 'bundler'
|
|
32
|
-
#
|
|
33
|
-
# begin
|
|
34
|
-
# Bundler.setup(:default, :development)
|
|
35
|
-
# rescue Bundler::BundlerError => e
|
|
36
|
-
# $stderr.puts e.message
|
|
37
|
-
# $stderr.puts "Run `bundle install` to install missing gems"
|
|
38
|
-
# exit e.status_code
|
|
39
|
-
# end
|
|
40
|
-
#
|
|
41
|
-
# require 'rake'
|
|
42
|
-
#
|
|
43
|
-
# require 'jeweler'
|
|
44
|
-
#
|
|
45
|
-
# Jeweler::Tasks.new do |gem|
|
|
46
|
-
# # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
|
47
|
-
# gem.name = "csv_madness"
|
|
48
|
-
# gem.homepage = "http://github.com/darthschmoo/csv_madness"
|
|
49
|
-
# gem.license = "MIT"
|
|
50
|
-
# gem.summary = "CSV Madness turns your CSV rows into happycrazy objects."
|
|
51
|
-
# gem.description = "CSV Madness removes what little pain is left from Ruby's CSV class. Load a CSV file, and get back an array of objects with customizable getter/setter methods."
|
|
52
|
-
# gem.email = "keeputahweird@gmail.com"
|
|
53
|
-
# gem.authors = ["Bryce Anderson"]
|
|
54
|
-
#
|
|
55
|
-
# # dependencies defined in Gemfile
|
|
56
|
-
# gem.files = Dir.glob( File.join( ".", "lib", "**", "*.rb" ) ) +
|
|
57
|
-
# Dir.glob( File.join( ".", "test", "**", "*" ) ) +
|
|
58
|
-
# %w( Gemfile Rakefile LICENSE.txt README.rdoc VERSION CHANGELOG.markdown csv_madness.gemspec )
|
|
59
|
-
#
|
|
60
|
-
# end
|
|
61
|
-
#
|
|
62
|
-
# Jeweler::RubygemsDotOrgTasks.new
|
|
63
|
-
#
|
|
64
|
-
# require 'rake/testtask'
|
|
65
|
-
# Rake::TestTask.new(:test) do |test|
|
|
66
|
-
# test.libs << 'lib' << 'test'
|
|
67
|
-
# test.pattern = 'test/**/test_*.rb'
|
|
68
|
-
# test.verbose = true
|
|
69
|
-
# end
|
|
70
|
-
#
|
|
71
|
-
# # require 'rcov/rcovtask'
|
|
72
|
-
# # Rcov::RcovTask.new do |test|
|
|
73
|
-
# # test.libs << 'test'
|
|
74
|
-
# # test.pattern = 'test/**/test_*.rb'
|
|
75
|
-
# # test.verbose = true
|
|
76
|
-
# # test.rcov_opts << '--exclude "gems/*"'
|
|
77
|
-
# # end
|
|
78
|
-
#
|
|
79
|
-
# task :default => :test
|
|
80
|
-
#
|
|
81
|
-
# require 'rdoc/task'
|
|
82
|
-
# Rake::RDocTask.new do |rdoc|
|
|
83
|
-
# version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
|
84
|
-
#
|
|
85
|
-
# rdoc.rdoc_dir = 'rdoc'
|
|
86
|
-
# rdoc.title = "csv_madness #{version}"
|
|
87
|
-
# rdoc.rdoc_files.include('README*')
|
|
88
|
-
# rdoc.rdoc_files.include('lib/**/*.rb')
|
|
89
|
-
# end
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.0.
|
|
1
|
+
0.0.10
|
data/lib/csv_madness/builder.rb
CHANGED
|
@@ -5,12 +5,14 @@ module CsvMadness
|
|
|
5
5
|
def initialize( &block )
|
|
6
6
|
@columns = {}
|
|
7
7
|
@column_syms = []
|
|
8
|
+
@column_counters = {}
|
|
8
9
|
|
|
9
10
|
@module = Module.new # for extending
|
|
10
11
|
self.extend( @module )
|
|
11
12
|
yield self if block_given?
|
|
12
13
|
end
|
|
13
14
|
|
|
15
|
+
|
|
14
16
|
def column( sym, method_path = nil, &block )
|
|
15
17
|
warn( "#{sym} already defined. Overwriting." ) if @column_syms.include?( sym )
|
|
16
18
|
|
|
@@ -23,6 +25,24 @@ module CsvMadness
|
|
|
23
25
|
Proc.new(&sym)
|
|
24
26
|
end
|
|
25
27
|
end
|
|
28
|
+
|
|
29
|
+
def column_names
|
|
30
|
+
@column_syms
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def constant_column( sym, const )
|
|
34
|
+
cproc = Utils::ConstProc.proc_for( const )
|
|
35
|
+
column( sym, &cproc )
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def blank_column( sym )
|
|
39
|
+
constant_column( sym, nil )
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def counter_column( sym, initial_value = 0 )
|
|
43
|
+
column( sym, &Utils::CounterProc.counter( initial_value ) )
|
|
44
|
+
end
|
|
45
|
+
|
|
26
46
|
|
|
27
47
|
# Three :on_error values:
|
|
28
48
|
# :print => Put an error message in the cell instead of a value
|
|
@@ -30,23 +50,34 @@ module CsvMadness
|
|
|
30
50
|
# :ignore => Hand back an empty cell
|
|
31
51
|
#
|
|
32
52
|
# Although ideally it should be configurable by column...
|
|
33
|
-
def build( objects, opts = {
|
|
53
|
+
def build( objects, opts = {} )
|
|
54
|
+
@progress_mode = choose_progress_mode( opts[:progress] )
|
|
55
|
+
debugger unless defined?( @show_progress )
|
|
56
|
+
|
|
57
|
+
@on_error = opts.fetch(:on_error){ :print }
|
|
58
|
+
@verbose = opts.fetch(:verbose){ false }
|
|
59
|
+
|
|
34
60
|
spreadsheet = CsvMadness::Sheet.new( @column_syms )
|
|
61
|
+
|
|
62
|
+
@objects = objects
|
|
63
|
+
@objects = @objects.records if @objects.is_a?( CsvMadness::Sheet )
|
|
35
64
|
|
|
36
|
-
for object in objects
|
|
37
|
-
STDOUT << "."
|
|
65
|
+
for object in @objects
|
|
38
66
|
record = {}
|
|
39
67
|
for sym in @column_syms
|
|
40
68
|
record[sym] = build_cell( object, sym, opts )
|
|
41
69
|
end
|
|
42
|
-
|
|
70
|
+
|
|
43
71
|
spreadsheet.add_record( record ) # hash form
|
|
72
|
+
show_progress
|
|
44
73
|
end
|
|
74
|
+
|
|
75
|
+
_reset_counter_columns
|
|
45
76
|
|
|
46
77
|
spreadsheet
|
|
47
78
|
end
|
|
48
79
|
|
|
49
|
-
def build_cell( object, sym, opts = {
|
|
80
|
+
def build_cell( object, sym, opts = {} )
|
|
50
81
|
column = @columns[sym]
|
|
51
82
|
|
|
52
83
|
case column
|
|
@@ -55,10 +86,12 @@ module CsvMadness
|
|
|
55
86
|
when Proc
|
|
56
87
|
build_cell_by_proc( object, column, opts )
|
|
57
88
|
else
|
|
58
|
-
|
|
89
|
+
debugger
|
|
90
|
+
"no idea what to do with #{column.inspect} (#{column.class})"
|
|
59
91
|
end
|
|
60
92
|
end
|
|
61
93
|
|
|
94
|
+
# ?????
|
|
62
95
|
def def( method_name, &block )
|
|
63
96
|
@module.send( :define_method, method_name, &block )
|
|
64
97
|
end
|
|
@@ -66,7 +99,7 @@ module CsvMadness
|
|
|
66
99
|
protected
|
|
67
100
|
def build_cell_by_pathstring( object, str, opts )
|
|
68
101
|
handle_cell_build_error( :build_cell_by_pathstring, opts ) do
|
|
69
|
-
for method in str.split(".")
|
|
102
|
+
for method in str.split(".")
|
|
70
103
|
object = object.send(method)
|
|
71
104
|
end
|
|
72
105
|
|
|
@@ -85,9 +118,9 @@ module CsvMadness
|
|
|
85
118
|
yield
|
|
86
119
|
end
|
|
87
120
|
rescue Exception => e
|
|
88
|
-
case
|
|
121
|
+
case @on_error
|
|
89
122
|
when nil, :print
|
|
90
|
-
puts "error #{e.message} #{caller}" if
|
|
123
|
+
puts "error #{e.message} #{caller}" if @verbose
|
|
91
124
|
"ERROR: #{e.message} (#{caller}())"
|
|
92
125
|
when :raise
|
|
93
126
|
puts "Re-raisinge error #{e.message}. Set opts[:on_error] to :print or :ignore if you want Builder to continue on errors."
|
|
@@ -96,5 +129,54 @@ module CsvMadness
|
|
|
96
129
|
""
|
|
97
130
|
end
|
|
98
131
|
end
|
|
132
|
+
|
|
133
|
+
def _reset_counter_columns
|
|
134
|
+
for sym, column in @columns
|
|
135
|
+
column.reset if column.is_a?( Utils::CounterProc )
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
#
|
|
140
|
+
def choose_progress_mode( m )
|
|
141
|
+
case m
|
|
142
|
+
when true
|
|
143
|
+
@show_progress = true
|
|
144
|
+
@progress_mode = progress_bar_available? ? :tty : :stdout
|
|
145
|
+
when false, nil
|
|
146
|
+
@show_progress = false
|
|
147
|
+
@progress_mode = :none
|
|
148
|
+
when Symbol
|
|
149
|
+
@show_progress = (m == :none) ? false : true
|
|
150
|
+
@progress_mode = m
|
|
151
|
+
else
|
|
152
|
+
warn "unknown progress mode #{m.inspect}"
|
|
153
|
+
choose_progress_mode( false )
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def show_progress
|
|
158
|
+
if @show_progress
|
|
159
|
+
@progress_mode ||= progress_bar_available? ? :tty : :stdout
|
|
160
|
+
|
|
161
|
+
case @progress_mode
|
|
162
|
+
when :tty
|
|
163
|
+
@tty_progress_bar ||= TTY::ProgressBar.new( "Building spreadsheet :current/:total (:percent) [:bar]", total: @objects.length )
|
|
164
|
+
@tty_progress_bar.advance(1)
|
|
165
|
+
when :stdout
|
|
166
|
+
STDOUT << "."
|
|
167
|
+
when :counter
|
|
168
|
+
unless defined?( @tty_progress_count )
|
|
169
|
+
puts ""
|
|
170
|
+
@tty_progress_count = 1
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
print "\r#{@tty_progress_count}/#{@objects.length} records written "
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def progress_bar_available?
|
|
179
|
+
defined?(TTY) && defined?(TTY::ProgressBar)
|
|
180
|
+
end
|
|
99
181
|
end
|
|
100
182
|
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module CsvMadness
|
|
2
|
+
class Column
|
|
3
|
+
include ColumnMethods::CoreMethods
|
|
4
|
+
include ColumnMethods::FetchMethods
|
|
5
|
+
include ColumnMethods::TypingMethods
|
|
6
|
+
include ColumnMethods::ErrorMethods
|
|
7
|
+
include ColumnMethods::DefaultValueMethods
|
|
8
|
+
|
|
9
|
+
attr_accessor :spreadsheet,
|
|
10
|
+
:index,
|
|
11
|
+
:name,
|
|
12
|
+
:type_conversion
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def initialize( _sheet, _name, _index, _type )
|
|
16
|
+
self.name = convert_column_name( nm )
|
|
17
|
+
self.index = index
|
|
18
|
+
self.aliases = @opts[:aliases]
|
|
19
|
+
self.set_type( opts[:type] )
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def get_cell( record )
|
|
23
|
+
record.data[self.index]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def set_cell( record, value )
|
|
27
|
+
record.data[self.index] = self.type_convert( value )
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module CsvMadness
|
|
2
|
+
module ColumnMethods
|
|
3
|
+
module ErrorMethods
|
|
4
|
+
# When a conversion fails, what happens?
|
|
5
|
+
#
|
|
6
|
+
# debug : enters debugger (test mode)
|
|
7
|
+
# ignore : no message is given and the default value is returned ("" for string, 0 for integer, 0.0 for float)?
|
|
8
|
+
# stdout : message printed to stdout
|
|
9
|
+
# stderr : message printed to stderr
|
|
10
|
+
# cell : message appears in the cell
|
|
11
|
+
attr_accessor :warning_style
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
attr_accessor :error_message
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module CsvMadness
|
|
2
|
+
module ColumnMethods
|
|
3
|
+
module TypingMethods
|
|
4
|
+
def type_convert( value )
|
|
5
|
+
if self.type_conversion
|
|
6
|
+
self.type_conversion.call( value )
|
|
7
|
+
else
|
|
8
|
+
value
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def set_type( type )
|
|
13
|
+
self.type_conversion = TypeConversion[@opts[:type]]
|
|
14
|
+
self.convert_column_to_type
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def convert_column_to_type
|
|
18
|
+
for record in self.spreadsheet.records
|
|
19
|
+
set_cell( record, get_cell( record ) )
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
module CsvMadness
|
|
2
|
+
class ColumnType
|
|
3
|
+
COLUMN_TYPE_LOOKUP = {
|
|
4
|
+
:integer => ColumnTypes::IntegerType,
|
|
5
|
+
:date => ColumnTypes::DateType,
|
|
6
|
+
:string => ColumnTypes::StringType,
|
|
7
|
+
# :number => ColumnTypes::NumberType,
|
|
8
|
+
:float => ColumnTypes::FloatType
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
DEFAULT_ERROR_MESSAGES = {
|
|
12
|
+
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# What is returned when a conversion fails?
|
|
17
|
+
#
|
|
18
|
+
# :default : the type conversion returns
|
|
19
|
+
# :blank : the cell becomes a nil
|
|
20
|
+
# :stderr : send warning message to stderr and return a nil
|
|
21
|
+
# :stdout : send warning message to stdout and return a nil
|
|
22
|
+
# :sheet : write the warning message into the sheet itself
|
|
23
|
+
attr_accessor :conversion_error_value
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def self.[]( t )
|
|
27
|
+
COLUMN_TYPE_LOOKUP[t]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def initialize( opts = {} )
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# default_hierarchy
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def standard_opts( overrides )
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def conversion_error_message( input )
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def handle_conversion_errors( input, &block )
|
|
49
|
+
begin
|
|
50
|
+
yield if block_given?
|
|
51
|
+
rescue ArgumentError
|
|
52
|
+
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def self.default_value
|
|
57
|
+
nil
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def default
|
|
61
|
+
self.default_value || self.class.default_value || nil
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
protected
|
|
65
|
+
def build_error_message( input, e )
|
|
66
|
+
if input =~ /CsvMadness::TypeError/
|
|
67
|
+
input
|
|
68
|
+
else
|
|
69
|
+
"CsvMadness::TypeError::#{ }"
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module CsvMadness
|
|
2
|
+
module ColumnTypes
|
|
3
|
+
class DateType < CsvMadness::ColumnType
|
|
4
|
+
# Blank inputs return nil. Other inputs may raise a date error
|
|
5
|
+
def self.convert( input )
|
|
6
|
+
if input.fwf_blank?
|
|
7
|
+
self.default_value
|
|
8
|
+
elsif input.is_a?(String)
|
|
9
|
+
Date.parse( input )
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module CsvMadness
|
|
2
|
+
module ColumnTypes
|
|
3
|
+
class FloatType < CsvMadness::ColumnType
|
|
4
|
+
|
|
5
|
+
# I suspect that a blank string and a nil should be treated the same, and that
|
|
6
|
+
# 0.0 is the wrong choice for a default. Maybe these should return :default or :error,
|
|
7
|
+
# and leave it to the individual column definition to handle that.
|
|
8
|
+
def self.convert( input )
|
|
9
|
+
if input.fwf_blank?
|
|
10
|
+
:default
|
|
11
|
+
elsif input.is_a?( String )
|
|
12
|
+
Float( input )
|
|
13
|
+
elsif input.respond_to?( :to_f )
|
|
14
|
+
input.to_f
|
|
15
|
+
elsif input.respond_to?( :to_i )
|
|
16
|
+
input.to_i.to_f
|
|
17
|
+
else
|
|
18
|
+
:error
|
|
19
|
+
end
|
|
20
|
+
rescue ArgumentError
|
|
21
|
+
:error
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module CsvMadness
|
|
2
|
+
module ColumnTypes
|
|
3
|
+
class IntegerType < CsvMadness::ColumnType
|
|
4
|
+
def self.convert( input )
|
|
5
|
+
if input.fwf_blank?
|
|
6
|
+
0
|
|
7
|
+
elsif input.is_a?( String )
|
|
8
|
+
Float( input ).round
|
|
9
|
+
elsif input.respond_to?( :to_f )
|
|
10
|
+
input.to_f.round
|
|
11
|
+
elsif input.respond_to?( :to_i )
|
|
12
|
+
input.to_i
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|