rgarner-csv-mapper 0.5.1 → 0.7.0

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.
data/Rakefile CHANGED
@@ -41,7 +41,7 @@ Rake::RDocTask.new do |rdoc|
41
41
  version = File.exist?('VERSION') ? File.read('VERSION') : ""
42
42
 
43
43
  rdoc.rdoc_dir = 'rdoc'
44
- rdoc.title = "csv-mapper #{version}"
44
+ rdoc.title = "rgarner-csv-mapper #{version}"
45
45
  rdoc.rdoc_files.include('README*')
46
46
  rdoc.rdoc_files.include('lib/**/*.rb')
47
47
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.1
1
+ 0.7.0
@@ -8,6 +8,10 @@ module CsvMapper
8
8
  def initialize(name, index, map_context)
9
9
  @name, @index, @map_context = name, index, map_context
10
10
  end
11
+
12
+ def to_s
13
+ "#{@index}: #{@name}"
14
+ end
11
15
 
12
16
  # Set the index that this map is targeting.
13
17
  #
@@ -51,5 +55,5 @@ module CsvMapper
51
55
  @transformer.call(csv_row, @index)
52
56
  end
53
57
  end
54
- end
58
+ end
55
59
  end
@@ -17,6 +17,7 @@ module CsvMapper
17
17
  @csv_data = csv_data
18
18
  @before_filters = []
19
19
  @after_filters = []
20
+ @named_columns = false
20
21
  @parser_options = {}
21
22
  @start_at_row = 0
22
23
  @stop_at_row = Infinity
@@ -49,17 +50,14 @@ module CsvMapper
49
50
  #
50
51
  # i.e. read_attributes_from_file('files+' => 'files_plus', 'files-' => 'files_minus)
51
52
  def read_attributes_from_file aliases = {}
52
- attributes = FasterCSV.new(@csv_data, @parser_options).readline
53
- @start_at_row = [ @start_at_row, 1 ].max
54
- @csv_data.rewind
55
53
  unnamed_number = 1
56
- attributes.each_with_index do |name, index|
54
+ iterate_headers do |name, index|
57
55
  if name.nil?
58
56
  name = "_field_#{unnamed_number}"
59
- unnamed_number += 1
57
+ unnamed_number += 1
60
58
  end
61
59
  name.strip!
62
- use_name = aliases[name] || name.gsub(/\s+/, '_').gsub(/[\W]+/, '').downcase
60
+ use_name = aliases[name] || attributize_field_name(name)
63
61
  add_attribute use_name, index
64
62
  end
65
63
  end
@@ -72,6 +70,12 @@ module CsvMapper
72
70
  @parser_options.merge :col_sep => @delimited_by
73
71
  end
74
72
 
73
+ # Default csv_mapper behaviour is to use the ordinal position of a mapped attribute.
74
+ # If you prefer to look for a column with the name of the attribute, use this method.
75
+ def named_columns
76
+ @named_columns = true
77
+ end
78
+
75
79
  # Convenience method to 'move' the cursor skipping the current index.
76
80
  def _SKIP_
77
81
  self.move_cursor
@@ -151,6 +155,17 @@ module CsvMapper
151
155
  # An optional first argument is used to move this maps cursor position and as the index of the
152
156
  # new AttributeMap
153
157
  def method_missing(name, *args) # :nodoc:
158
+ existing_map = self.mapped_attributes.find {|attr| attr.name == name}
159
+ return existing_map if existing_map
160
+
161
+ # Effectively add an alias when we see new_field('With/Aliased/Name')
162
+ if args[0].is_a? String
163
+ return add_attribute(name, headers_to_indices.fetch(args[0].downcase))
164
+ end
165
+
166
+ if @named_columns
167
+ return add_attribute(name, headers_to_indices.fetch(name.to_s))
168
+ end
154
169
 
155
170
  if index = args[0]
156
171
  self.move_cursor(index - self.cursor)
@@ -168,6 +183,20 @@ module CsvMapper
168
183
  end).flatten!
169
184
  end
170
185
 
186
+ def iterate_headers
187
+ attributes = FasterCSV.new(@csv_data, @parser_options).readline
188
+ @start_at_row = [ @start_at_row, 1 ].max
189
+ @csv_data.rewind
190
+ attributes.each_with_index { |name, index| yield name, index }
191
+ end
192
+
193
+ def headers_to_indices
194
+ return @h_to_i if @h_to_i
195
+ @h_to_i = {}
196
+ iterate_headers { |name, index| @h_to_i[name.strip.downcase] = index if name }
197
+ @h_to_i
198
+ end
199
+
171
200
  def map_to_class # :nodoc:
172
201
  unless @map_to_klass
173
202
  attrs = mapped_attributes.collect {|attr_map| attr_map.name}
@@ -180,5 +209,9 @@ module CsvMapper
180
209
  def cursor=(value) # :nodoc:
181
210
  @cursor=value
182
211
  end
212
+
213
+ def attributize_field_name(name)
214
+ name.gsub(/\s+/, '_').gsub(/[\W]+/, '').downcase
215
+ end
183
216
  end
184
217
  end
@@ -143,6 +143,44 @@ describe CsvMapper do
143
143
  results[1].number_of_years_old.should == '26'
144
144
  end
145
145
 
146
+ describe "Adding only certain attributes by name or alias" do
147
+ before :all do
148
+ @results = CsvMapper.import(File.dirname(__FILE__) + '/test_with_empty_column_names.csv') do
149
+ named_columns
150
+ surname('Last Name')
151
+ age.map { |row, index| row[index].to_i }
152
+ end
153
+ end
154
+
155
+ it "should have Last name aliased as surname" do
156
+ @results[1].surname.should == 'Doe'
157
+ end
158
+
159
+ it "should transform age to 26 (a Fixnum)" do
160
+ @results[1].age.should == 26
161
+ end
162
+
163
+ it "should not have First Name at all" do
164
+ lambda { @results[1].first_name }.should raise_error(NoMethodError)
165
+ end
166
+
167
+ it "should raise IndexError when adding non-existent fields" do
168
+ lambda {
169
+ @results = CsvMapper.import(File.dirname(__FILE__) + '/test_with_empty_column_names.csv') do
170
+ add_attributes_by_name('doesnt_exist')
171
+ end
172
+ }.should raise_error(IndexError)
173
+ end
174
+
175
+ it "should raise IndexError when adding non-existent aliases" do
176
+ lambda {
177
+ @results = CsvMapper.import(File.dirname(__FILE__) + '/test_with_empty_column_names.csv') do
178
+ my_new_field('doesnt_exist')
179
+ end
180
+ }.should raise_error(IndexError)
181
+ end
182
+ end
183
+
146
184
  it "should be able to assign default column names when column names are null" do
147
185
  results = CsvMapper.import(File.dirname(__FILE__) + '/test_with_empty_column_names.csv') do
148
186
  read_attributes_from_file
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rgarner-csv-mapper
3
3
  version: !ruby/object:Gem::Version
4
- hash: 9
4
+ hash: 3
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 5
9
- - 1
10
- version: 0.5.1
8
+ - 7
9
+ - 0
10
+ version: 0.7.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Luke Pillow
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-08-25 00:00:00 +01:00
19
+ date: 2010-08-27 00:00:00 +01:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency