csv_madness 0.0.6 → 0.0.9
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.
- checksums.yaml +5 -13
- data/Gemfile +2 -3
- data/README.rdoc +55 -47
- data/Rakefile +79 -52
- data/VERSION +1 -1
- data/lib/csv_madness/builder.rb +4 -1
- data/lib/csv_madness/data_accessor_module.rb +59 -24
- data/lib/csv_madness/exceptions.rb +16 -0
- data/lib/csv_madness/record.rb +3 -1
- data/lib/csv_madness/sheet.rb +33 -387
- data/lib/csv_madness/sheet_methods/base.rb +6 -0
- data/lib/csv_madness/sheet_methods/class_methods.rb +77 -0
- data/lib/csv_madness/sheet_methods/column_methods.rb +187 -0
- data/lib/csv_madness/sheet_methods/file_methods.rb +41 -0
- data/lib/csv_madness/sheet_methods/indexing.rb +52 -0
- data/lib/csv_madness/sheet_methods/record_methods.rb +99 -0
- data/lib/csv_madness.rb +1 -2
- data/test/helper.rb +5 -0
- data/test/test_builder.rb +8 -4
- data/test/test_csv_madness.rb +6 -7
- data/test/test_reloading_spreadsheet.rb +2 -1
- data/test/test_sheet.rb +28 -18
- metadata +54 -36
checksums.yaml
CHANGED
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
|
|
5
|
-
data.tar.gz: !binary |-
|
|
6
|
-
ZTRkOWNjMjYyNTNmMjA3YzMwZThlMzAyOWRjMTM0ZWYwMTQ3NWE0MA==
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 4f4f9b06af750b458f7eb43b10053dfce2b60a69cc55ea4410d4466c72680f0c
|
|
4
|
+
data.tar.gz: 23ddbf472f0b52973769e21eb72939622bee0e5b13e43e8c292ae28203106145
|
|
7
5
|
SHA512:
|
|
8
|
-
metadata.gz:
|
|
9
|
-
|
|
10
|
-
Zjg2ZjA5ZGZlZTEyNjg1NjFmNzE5NzY3NTFhNzY3ZTIyNDFhZGIzZTEzOGI5
|
|
11
|
-
ZDUzMjZjYjJkODdiM2M1M2JiMjZiMGNlMTViNWE2Yzk1ZjU1YjI=
|
|
12
|
-
data.tar.gz: !binary |-
|
|
13
|
-
MjJlYzI1YTQxMzU4NzA0MmVlNzFkYzVmNDE3NjYyMDM5YmI3Y2JmMmQyOWZk
|
|
14
|
-
OGQ0NzFhODUyMzRjNWI3ZWRlZDQ3YmQ0NGU0Zjc4ZDFmNWRkMWY4MDc4OTdi
|
|
15
|
-
YjkwY2U1MGY3MmVhNTY2NTYzYzc1ZDViZWViMTg0OTE5OGU1ZTE=
|
|
6
|
+
metadata.gz: 1e44f1666c4118cf68a16f254ea5ad8808f9a0036b346755d187c74baf24a65cff718323d81741cd5478b036fcea3518daa3b2b5f72f6de2bf89b3b435392de8
|
|
7
|
+
data.tar.gz: b44d0fa470ec59317f5a93b0e73d1ec6a032f300083734e2b0aef27b2077b51303dce1b504e77102e6cfb5f79cc2c229d136d4a5d7eca049402bb88e740e711a
|
data/Gemfile
CHANGED
data/README.rdoc
CHANGED
|
@@ -7,62 +7,62 @@ CSV Madness tries to remove what little pain is left from Ruby's CSV class. Loa
|
|
|
7
7
|
|
|
8
8
|
== Why should I use it?
|
|
9
9
|
|
|
10
|
-
I like brief code and I cannot lie.
|
|
10
|
+
I like brief code and I cannot lie.
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
== Examples
|
|
14
14
|
|
|
15
15
|
CsvMadness makes some assumptions about your CSV file. It does assume headers, for example.
|
|
16
16
|
|
|
17
|
-
The simplest case is when your columns are nicely named. For example, if you have a csv file named
|
|
17
|
+
The simplest case is when your columns are nicely named. For example, if you have a csv file named `~/data/people.csv`:
|
|
18
|
+
|
|
19
|
+
"id","fname","lname","age","born"
|
|
20
|
+
"1","Mary","Moore","27","1986-04-08 15:06:10"
|
|
21
|
+
"2","Bill","Paxton","39","1974-02-22"
|
|
22
|
+
"3","Charles","Darwin","72",""
|
|
23
|
+
"4","Chuck","Norris","57","1901-03-02"
|
|
18
24
|
|
|
19
|
-
<code>
|
|
20
|
-
"id","fname","lname","age","born"
|
|
21
|
-
"1","Mary","Moore","27","1986-04-08 15:06:10"
|
|
22
|
-
"2","Bill","Paxton","39","1974-02-22"
|
|
23
|
-
"3","Charles","Darwin","72",""
|
|
24
|
-
"4","Chuck","Norris","57","1901-03-02"
|
|
25
|
-
</code>
|
|
26
25
|
|
|
27
26
|
... then you can write code like so:
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
sheet
|
|
32
|
-
sheet.
|
|
33
|
-
sheet.
|
|
34
|
-
sheet.
|
|
35
|
-
sheet.
|
|
36
|
-
|
|
37
|
-
|
|
28
|
+
require 'csv_madness'
|
|
29
|
+
|
|
30
|
+
sheet = CsvMadness.load( "~/data/people.csv" )
|
|
31
|
+
sheet.columns # => [:id, :fname, :lname, :age, :born]
|
|
32
|
+
sheet.records.map(&:id) # => ["1", "2", "3", "4"]
|
|
33
|
+
sheet.set_column_type(:id, :float)
|
|
34
|
+
sheet.records.map(&:id) # => [1.0, 2.0, 3.0, 4.0]
|
|
35
|
+
sheet.alter_column(:id) do |id|
|
|
36
|
+
id + rand() - 0.5
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
sheet.records.map(&:id) # => [0.7186, 2.30134, 2.90132, 4.30124] (your results may vary)
|
|
40
|
+
mary = sheet[0]
|
|
38
41
|
|
|
39
|
-
|
|
40
|
-
mary = sheet[0]
|
|
42
|
+
"#{mary.lname}, #{mary.fname} (#{mary.id})" # => "Moore, Mary (1)"
|
|
41
43
|
|
|
42
|
-
"#{mary.lname}, #{mary.fname} (#{mary.id})" # => "Moore, Mary (1)"
|
|
43
|
-
'''
|
|
44
44
|
|
|
45
45
|
If you're not satisfied with your column names, you can send your own, in the column order. An index can also be provided, which will allow you to use <tt>.fetch()</tt> to find specific records quickly:
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
sheet = CsvMadness.load( "~/data/people.csv",
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
require 'csv_madness'
|
|
48
|
+
sheet = CsvMadness.load( "~/data/people.csv",
|
|
49
|
+
columns: [:uid, :first_name, :last_name, :years_on_planet, :birthday],
|
|
50
|
+
index: :uid )
|
|
51
|
+
|
|
52
|
+
sheet.fetch("2").years_on_planet # => "39"
|
|
51
53
|
|
|
52
|
-
sheet.fetch("2").years_on_planet # => "39"
|
|
53
|
-
'''
|
|
54
54
|
|
|
55
55
|
**Note:** you can provide multiple indexes as an array. However many columns you index, you'll run into trouble if the index isn't unique for each record. (that may change in the future)
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
It's useful to clean up your files. Say you have:
|
|
59
59
|
|
|
60
|
-
"
|
|
61
|
-
"1 ","Mary ","Moore","27","1986-04-08 15:06:10"
|
|
62
|
-
""," Bill ","Paxton",," Feb. 22, 1974 "
|
|
63
|
-
,"Charles "," Darwin","72 "
|
|
64
|
-
"4","Chuck","Norris",," 2 March 1901 "
|
|
65
|
-
|
|
60
|
+
"id","fname","lname","age"," born "
|
|
61
|
+
"1 ","Mary ","Moore","27","1986-04-08 15:06:10"
|
|
62
|
+
""," Bill ","Paxton",," Feb. 22, 1974 "
|
|
63
|
+
"3","Charles "," Darwin","72 "
|
|
64
|
+
"4","Chuck","Norris",," 2 March 1901 "
|
|
65
|
+
|
|
66
66
|
|
|
67
67
|
Ick. Missing IDs, inconsistent date formats, leading and trailing whitespace... We can fix this.
|
|
68
68
|
|
|
@@ -163,27 +163,35 @@ You could do something similar to clean and standardize phone numbers, detect an
|
|
|
163
163
|
|
|
164
164
|
You have an array of objects. You want to write them to a spreadsheet.
|
|
165
165
|
|
|
166
|
-
```ruby
|
|
167
166
|
sb = CsvMadness::Builder.new do |sb|
|
|
168
167
|
sb.column( :id )
|
|
169
|
-
sb.column( :addressee,
|
|
170
|
-
sb.column( :
|
|
171
|
-
sb.column( :
|
|
172
|
-
sb.column( :city,
|
|
173
|
-
sb.column( :state_code,
|
|
174
|
-
sb.column( :formatted_zip,
|
|
175
|
-
sb.column( :phone,
|
|
176
|
-
sb.column( :
|
|
177
|
-
sb.column( :
|
|
178
|
-
sb.column( :
|
|
168
|
+
sb.column( :addressee, "addressee_custom" )
|
|
169
|
+
sb.column( :street, "primary_address.street_address" )
|
|
170
|
+
sb.column( :street2, "primary_address.supplemental_address_1" )
|
|
171
|
+
sb.column( :city, "primary_address.city" )
|
|
172
|
+
sb.column( :state_code, "primary_address.state_code" )
|
|
173
|
+
sb.column( :formatted_zip, "primary_address.formatted_zip" )
|
|
174
|
+
sb.column( :phone, "phones.first.phone" )
|
|
175
|
+
sb.column( :contact, "congregation_fieldset.congregation_leader" )
|
|
176
|
+
sb.column( :email, "emails.first.email" )
|
|
177
|
+
sb.column( :greeting ) do |contact|
|
|
178
|
+
if contact.business?
|
|
179
|
+
"To our friends at #{contact.organization_name},"
|
|
180
|
+
elsif contact.person?
|
|
181
|
+
"Dear #{ contact.title } #{ contact.last_name }"
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
179
185
|
end
|
|
180
186
|
|
|
181
187
|
sheet = sb.build( [address1, address2, address3...] )
|
|
182
|
-
|
|
188
|
+
|
|
189
|
+
outfile = FunWith::Files::FilePath.home.join( "Documents", "addresses", "address_records.csv" )
|
|
190
|
+
sheet.write_to_file( outfile )
|
|
183
191
|
|
|
184
192
|
=== Documentation is incomplete ===
|
|
185
193
|
|
|
186
|
-
There are
|
|
194
|
+
There are other features, but they'll take time to test and document.
|
|
187
195
|
|
|
188
196
|
|
|
189
197
|
|
data/Rakefile
CHANGED
|
@@ -1,62 +1,89 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
|
+
require 'fun_with_gems'
|
|
3
|
+
require_relative File.join( "lib", "csv_madness" )
|
|
4
|
+
self.extend( FunWith::Gems::Rakefile)
|
|
2
5
|
|
|
3
|
-
|
|
4
|
-
require 'bundler'
|
|
6
|
+
rakefile_setup CsvMadness
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
require 'jeweler'
|
|
8
|
+
gem_specification do |gem|
|
|
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"]
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
gem.summary = "CSV Madness turns your CSV rows into happycrazy objects."
|
|
24
|
-
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."
|
|
25
|
-
gem.email = "keeputahweird@gmail.com"
|
|
26
|
-
gem.authors = ["Bryce Anderson"]
|
|
27
|
-
|
|
28
|
-
# dependencies defined in Gemfile
|
|
29
|
-
gem.files = Dir.glob( File.join( ".", "lib", "**", "*.rb" ) ) +
|
|
30
|
-
Dir.glob( File.join( ".", "test", "**", "*" ) ) +
|
|
31
|
-
%w( Gemfile Rakefile LICENSE.txt README.rdoc VERSION CHANGELOG.markdown )
|
|
32
|
-
|
|
19
|
+
# dependencies defined in Gemfile
|
|
20
|
+
gem.files = Dir.glob( File.join( ".", "lib", "**", "*.rb" ) ) +
|
|
21
|
+
Dir.glob( File.join( ".", "test", "**", "*" ) ) +
|
|
22
|
+
%w( Gemfile Rakefile LICENSE.txt README.rdoc VERSION CHANGELOG.markdown )
|
|
23
|
+
# csv_madness.gemspec )
|
|
33
24
|
end
|
|
34
25
|
|
|
35
|
-
|
|
26
|
+
setup_gem_boilerplate
|
|
36
27
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
#
|
|
45
|
-
#
|
|
46
|
-
#
|
|
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'
|
|
47
67
|
# test.pattern = 'test/**/test_*.rb'
|
|
48
68
|
# test.verbose = true
|
|
49
|
-
# test.rcov_opts << '--exclude "gems/*"'
|
|
50
69
|
# end
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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.9
|
data/lib/csv_madness/builder.rb
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
module CsvMadness
|
|
2
2
|
class Builder
|
|
3
|
+
attr_accessor :label
|
|
4
|
+
|
|
3
5
|
def initialize( &block )
|
|
4
6
|
@columns = {}
|
|
5
7
|
@column_syms = []
|
|
8
|
+
|
|
6
9
|
@module = Module.new # for extending
|
|
7
10
|
self.extend( @module )
|
|
8
|
-
yield self
|
|
11
|
+
yield self if block_given?
|
|
9
12
|
end
|
|
10
13
|
|
|
11
14
|
def column( sym, method_path = nil, &block )
|
|
@@ -1,44 +1,79 @@
|
|
|
1
|
+
# Each record within the spreadsheet is extended by a module with accessor functions
|
|
2
|
+
# which allow the user to treat column names as methods. When columns are added, dropped, or re-ordered,
|
|
3
|
+
# the accessor module needs to be updated to reflect the change.
|
|
1
4
|
class DataAccessorModule < Module
|
|
5
|
+
# mapping : keys = column symbol
|
|
6
|
+
# values = column index
|
|
7
|
+
attr_accessor :column_accessors_map
|
|
8
|
+
|
|
2
9
|
def initialize( mapping )
|
|
3
|
-
|
|
4
|
-
|
|
10
|
+
puts "Got mapping #{mapping.inspect}"
|
|
11
|
+
@column_accessors_map = mapping
|
|
12
|
+
remap_accessors
|
|
5
13
|
end
|
|
6
14
|
|
|
7
|
-
def install_column_accessors(
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
15
|
+
def install_column_accessors( *columns )
|
|
16
|
+
for column in columns.flatten
|
|
17
|
+
unless is_valid_ruby_method?( column )
|
|
18
|
+
warn( "#{column.inspect} is not a valid ruby method" )
|
|
19
|
+
require "data_accessor_module" # TODO: WTF?
|
|
20
|
+
column = "csv_column_#{index}"
|
|
21
|
+
warn( " ----> renaming to #{column.inspect}" )
|
|
12
22
|
end
|
|
23
|
+
|
|
24
|
+
if self.respond_to?( column )
|
|
25
|
+
puts "Column already has accessors"
|
|
26
|
+
else
|
|
27
|
+
eval <<-EOF
|
|
28
|
+
self.send( :define_method, :#{column} ) do
|
|
29
|
+
self.csv_data[ self.column_accessors_map[ :#{column} ] ]
|
|
30
|
+
end
|
|
13
31
|
|
|
14
|
-
|
|
15
|
-
|
|
32
|
+
self.send( :define_method, :#{column}= ) do |val|
|
|
33
|
+
self.csv_data[ self.column_accessors_map[ :#{column} ] ] = val
|
|
34
|
+
end
|
|
35
|
+
EOF
|
|
16
36
|
end
|
|
17
|
-
|
|
37
|
+
end
|
|
18
38
|
end
|
|
19
39
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
40
|
+
# But if instead of hardcoding the index, the index was pulled from the spreadsheet mapping...
|
|
41
|
+
# a titch slower to look up? But a change to the mapping automatically updates the method
|
|
42
|
+
def remove_column_accessors( *columns )
|
|
43
|
+
for column in columns.flatten
|
|
44
|
+
for method_sym in [column, :"#{column}="]
|
|
45
|
+
self.send( :remove_method, method_sym ) if self.respond_to?( method_sym )
|
|
46
|
+
end
|
|
47
|
+
end
|
|
23
48
|
end
|
|
24
49
|
|
|
25
50
|
def remove_all_column_accessors
|
|
26
|
-
|
|
51
|
+
# 2016-11-24 : was this necessary for anything
|
|
52
|
+
# @column_accessors ||= []
|
|
53
|
+
remove_column_accessors( @column_accessors_map.keys )
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Partly obsoleted.
|
|
57
|
+
def remap_accessors( *args )
|
|
58
|
+
#
|
|
27
59
|
|
|
28
|
-
|
|
29
|
-
|
|
60
|
+
|
|
61
|
+
remove_all_column_accessors
|
|
62
|
+
|
|
63
|
+
if args.length == 1
|
|
64
|
+
debugger
|
|
65
|
+
@column_accessors_map = args.first
|
|
30
66
|
end
|
|
31
67
|
|
|
32
|
-
@
|
|
68
|
+
install_column_accessors( @column_accessors_map.keys )
|
|
33
69
|
end
|
|
34
70
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
71
|
+
# Symbol.inspect doesn't output " quotes when given a sym
|
|
72
|
+
# that expresses a valid method name or a valid identifier.
|
|
73
|
+
def is_valid_ruby_method?( str_or_sym )
|
|
74
|
+
sym = str_or_sym.to_sym
|
|
75
|
+
test_string = sym.inspect
|
|
39
76
|
|
|
40
|
-
|
|
41
|
-
install_column_accessors( column, index )
|
|
42
|
-
end
|
|
77
|
+
test_string.match( /^:[@"]/ ).nil?
|
|
43
78
|
end
|
|
44
79
|
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module CsvMadness
|
|
2
|
+
class LoadError < RuntimeError
|
|
3
|
+
end
|
|
4
|
+
|
|
5
|
+
class ColumnError < ArgumentError
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class ForbiddenColumnNameError < ColumnError
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class MissingColumnError < ColumnError
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class ColumnExistsError < ColumnError
|
|
15
|
+
end
|
|
16
|
+
end
|
data/lib/csv_madness/record.rb
CHANGED
|
@@ -8,8 +8,10 @@ module CsvMadness
|
|
|
8
8
|
# symbol.
|
|
9
9
|
class Record
|
|
10
10
|
attr_accessor :csv_data
|
|
11
|
+
attr_reader :column_accessors_map
|
|
11
12
|
|
|
12
|
-
def initialize( data )
|
|
13
|
+
def initialize( data, mapping )
|
|
14
|
+
@column_accessors_map = mapping # holds a reference to its spreadsheet's overall mapping
|
|
13
15
|
import_record_data( data )
|
|
14
16
|
end
|
|
15
17
|
|