csv-mapper 0.0.3 → 0.0.4

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.
@@ -1,3 +1,8 @@
1
+ == 0.0.4 2009-08-05
2
+ * Merged contributions from Jeffrey Chupp - http://semanticart.com
3
+ * Added support for "Automagical Attribute Discovery"
4
+ * Added Ruby 1.9 compatibility
5
+
1
6
  == 0.0.3 2008-12-22
2
7
  * Fixed specs to work with RSpec 1.1.9 and later where Modules aren't auto included
3
8
 
@@ -1,10 +1,8 @@
1
1
  = README
2
2
 
3
- by Luke Pillow
4
-
5
3
  == DESCRIPTION:
6
4
 
7
- CsvMapper is a small library intended to simplify the common steps involved with importing CSV files to a usable form in Ruby.
5
+ CsvMapper is a small library intended to simplify the common steps involved with importing CSV files to a usable form in Ruby. CsvMapper is compatible with recent 1.8 versions of Ruby as well as Ruby 1.9+
8
6
 
9
7
  == EXAMPLES:
10
8
 
@@ -30,6 +28,17 @@ The following example will import a CSV file to an Array of OpenStruct[http://ru
30
28
  results.first.last_name # Doe
31
29
  results.first.age # 27
32
30
 
31
+ ==== Automagical Attribute Discovery Example
32
+ include CsvMapper
33
+
34
+ results = import('/path/to/file.csv') do
35
+ read_attributes_from_file
36
+ end
37
+
38
+ results.first.first_name # John
39
+ results.first.last_name # Doe
40
+ results.first.age # 27
41
+
33
42
  ==== Import to ActiveRecord Example
34
43
  Although CsvMapper has no dependency on ActiveRecord; it's easy to import a CSV file to ActiveRecord models and save them.
35
44
 
@@ -50,7 +59,7 @@ See CsvMapper for a more detailed description
50
59
 
51
60
  == REQUIREMENTS:
52
61
 
53
- FasterCSV[http://fastercsv.rubyforge.org/]
62
+ FasterCSV[http://fastercsv.rubyforge.org/] on pre 1.9 versions of Ruby
54
63
 
55
64
  == INSTALL:
56
65
 
@@ -2,7 +2,21 @@ $:.unshift(File.dirname(__FILE__)) unless
2
2
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
3
 
4
4
  require 'ostruct'
5
- require 'fastercsv'
5
+
6
+ # the following is slightly modified from Gregory Brown's
7
+ # solution on the Ruport Blaag:
8
+ # http://ruport.blogspot.com/2008/03/fastercsv-api-shim-for-19.html
9
+ if RUBY_VERSION > "1.9"
10
+ require "csv"
11
+ unless defined? FCSV
12
+ class Object
13
+ FasterCSV = CSV
14
+ alias_method :FasterCSV, :CSV
15
+ end
16
+ end
17
+ else
18
+ require "fastercsv"
19
+ end
6
20
 
7
21
  # This module provides the main interface for importing CSV files & data to mapped Ruby objects.
8
22
  # = Usage
@@ -67,7 +81,7 @@ require 'fastercsv'
67
81
  # other_results = import('/path/to/file.csv', :map => a_row_map)
68
82
  #
69
83
  module CsvMapper
70
- VERSION = '0.0.3'
84
+ VERSION = '0.0.4'
71
85
 
72
86
  # Create a new RowMap instance from the definition in the given block.
73
87
  def map_csv(&map_block)
@@ -82,10 +96,11 @@ module CsvMapper
82
96
  # <tt>:map</tt>:: Specify an instance of a RowMap to take presidence over a given block defintion.
83
97
  #
84
98
  def import(data, options={}, &map_block)
99
+ csv_data = options[:type] == :io ? data : File.new(data, 'r')
100
+
85
101
  config = { :type => :file_path,
86
- :map => map_csv(&map_block) }.merge!(options)
87
-
88
- csv_data = config[:type] == :io ? data : File.new(data, 'r')
102
+ :map => map_csv_with_data(csv_data, &map_block) }.merge!(options)
103
+
89
104
  map = config[:map]
90
105
 
91
106
  results = []
@@ -107,8 +122,9 @@ module CsvMapper
107
122
  attr_reader :mapped_attributes
108
123
 
109
124
  # Create a new instance with access to an evaluation context
110
- def initialize(context, &map_block)
125
+ def initialize(context, csv_data = nil, &map_block)
111
126
  @context = context
127
+ @csv_data = csv_data
112
128
  @before_filters = []
113
129
  @after_filters = []
114
130
  @parser_options = {}
@@ -133,6 +149,26 @@ module CsvMapper
133
149
  end
134
150
  end
135
151
 
152
+ # Allow us to read the first line of a csv file to automatically generate the attribute names.
153
+ # Spaces are replaced with underscores and non-word characters are removed.
154
+ #
155
+ # Keep in mind that there is potential for overlap in using this (i.e. you have a field named
156
+ # files+ and one named files- and they both get named 'files').
157
+ #
158
+ # You can specify aliases to rename fields to prevent conflicts and/or improve readability and compatibility.
159
+ #
160
+ # i.e. read_attributes_from_file('files+' => 'files_plus', 'files-' => 'files_minus)
161
+ def read_attributes_from_file aliases = {}
162
+ attributes = FasterCSV.new(@csv_data, @parser_options).readline
163
+ @start_at_row = [ @start_at_row, 1 ].max
164
+ @csv_data.rewind
165
+ attributes.each_with_index do |name, index|
166
+ name.strip!
167
+ use_name = aliases[name] || name.gsub(/\s+/, '_').gsub(/[\W]+/, '').downcase
168
+ add_attribute use_name, index
169
+ end
170
+ end
171
+
136
172
  # Specify a hash of FasterCSV options to be used for CSV parsing
137
173
  #
138
174
  # Can be anything FasterCSV::new()[http://fastercsv.rubyforge.org/classes/FasterCSV.html#M000018] accepts
@@ -299,4 +335,10 @@ module CsvMapper
299
335
  end
300
336
 
301
337
  end
338
+
339
+ protected
340
+ # Create a new RowMap instance from the definition in the given block and pass the csv_data.
341
+ def map_csv_with_data(csv_data, &map_block) # :nodoc:
342
+ CsvMapper::RowMap.new(self, csv_data, &map_block)
343
+ end
302
344
  end
@@ -49,7 +49,17 @@ describe CsvMapper do
49
49
 
50
50
  results.size.should == 2
51
51
  end
52
-
52
+
53
+ it "should be able to read attributes from a csv file" do
54
+ results = import(File.dirname(__FILE__) + '/test.csv') do
55
+ # we'll alias age here just as an example
56
+ read_attributes_from_file('Age' => 'number_of_years_old')
57
+ end
58
+ results[1].first_name.should == 'Jane'
59
+ results[1].last_name.should == 'Doe'
60
+ results[1].number_of_years_old.should == '26'
61
+ end
62
+
53
63
  it "should import non-comma delimited files" do
54
64
  piped_io = 'foo|bar|00|01'
55
65
 
@@ -35,7 +35,7 @@
35
35
  <div class="sidebar">
36
36
  <div id="version" class="clickable" onclick='document.location = "http://rubyforge.org/projects/csv-mapper"; return false'>
37
37
  <p>Get Version</p>
38
- <a href="http://rubyforge.org/projects/csv-mapper" class="numbers">0.0.1</a>
38
+ <a href="http://rubyforge.org/projects/csv-mapper" class="numbers">0.0.4</a>
39
39
  </div>
40
40
  </div>
41
41
  <h2>What</h2>
@@ -66,6 +66,18 @@ Bat,Man,52
66
66
  <span class="punct">[</span><span class="ident">first_name</span><span class="punct">,</span> <span class="ident">last_name</span><span class="punct">,</span> <span class="ident">age</span><span class="punct">]</span>
67
67
  <span class="keyword">end</span>
68
68
 
69
+ <span class="ident">results</span><span class="punct">.</span><span class="ident">first</span><span class="punct">.</span><span class="ident">first_name</span> <span class="comment"># John</span>
70
+ <span class="ident">results</span><span class="punct">.</span><span class="ident">first</span><span class="punct">.</span><span class="ident">last_name</span> <span class="comment"># Doe</span>
71
+ <span class="ident">results</span><span class="punct">.</span><span class="ident">first</span><span class="punct">.</span><span class="ident">age</span> <span class="comment"># 27</span>
72
+ </pre></p>
73
+ <h3>Automagical Attribute Discovery Example</h3>
74
+ <p><pre class='syntax'>
75
+ <span class="ident">include</span> <span class="constant">CsvMapper</span>
76
+
77
+ <span class="ident">results</span> <span class="punct">=</span> <span class="ident">import</span><span class="punct">('</span><span class="string">/path/to/file.csv</span><span class="punct">')</span> <span class="keyword">do</span>
78
+ <span class="ident">read_attributes_from_file</span>
79
+ <span class="keyword">end</span>
80
+
69
81
  <span class="ident">results</span><span class="punct">.</span><span class="ident">first</span><span class="punct">.</span><span class="ident">first_name</span> <span class="comment"># John</span>
70
82
  <span class="ident">results</span><span class="punct">.</span><span class="ident">first</span><span class="punct">.</span><span class="ident">last_name</span> <span class="comment"># Doe</span>
71
83
  <span class="ident">results</span><span class="punct">.</span><span class="ident">first</span><span class="punct">.</span><span class="ident">age</span> <span class="comment"># 27</span>
@@ -106,7 +118,7 @@ rake install_gem</pre>
106
118
  <h2>Contact</h2>
107
119
  <p>Comments are welcome. Send an email to <a href="mailto:lpillow@gmail.com">Luke Pillow</a> email via the <a href="http://groups.google.com/group/csv-mapper">forum</a></p>
108
120
  <p class="coda">
109
- <a href="http://www.pillowfactory.org">Luke Pillow</a>, 5th December 2008<br>
121
+ <a href="http://www.pillowfactory.org">Luke Pillow</a>, 5th August 2009<br>
110
122
  Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
111
123
  </p>
112
124
  </div>
@@ -45,6 +45,20 @@ results.first.last_name # Doe
45
45
  results.first.age # 27
46
46
  </pre>
47
47
 
48
+ h3. Automagical Attribute Discovery Example
49
+
50
+ <pre syntax="ruby">
51
+ include CsvMapper
52
+
53
+ results = import('/path/to/file.csv') do
54
+ read_attributes_from_file
55
+ end
56
+
57
+ results.first.first_name # John
58
+ results.first.last_name # Doe
59
+ results.first.age # 27
60
+ </pre>
61
+
48
62
  h3. Import to ActiveRecord Example
49
63
 
50
64
  Although CSV Mapper has no dependency on ActiveRecord; it‘s easy to import a CSV file to ActiveRecord models and save them.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: csv-mapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luke Pillow
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-12-22 00:00:00 -06:00
12
+ date: 2009-08-05 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -30,7 +30,7 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 1.2.1
33
+ version: 1.2.3
34
34
  version:
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: hoe
@@ -42,7 +42,7 @@ dependencies:
42
42
  - !ruby/object:Gem::Version
43
43
  version: 1.8.0
44
44
  version:
45
- description: CsvMapper is a small library intended to simplify the common steps involved with importing CSV files to a usable form in Ruby.
45
+ description: CsvMapper is a small library intended to simplify the common steps involved with importing CSV files to a usable form in Ruby. CsvMapper is compatible with recent 1.8 versions of Ruby as well as Ruby 1.9+
46
46
  email:
47
47
  - lpillow@gmail.com
48
48
  executables: []
@@ -82,7 +82,9 @@ files:
82
82
  - website/stylesheets/screen.css
83
83
  - website/template.html.erb
84
84
  has_rdoc: true
85
- homepage: by Luke Pillow
85
+ homepage:
86
+ licenses: []
87
+
86
88
  post_install_message:
87
89
  rdoc_options:
88
90
  - --main
@@ -104,10 +106,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
106
  requirements: []
105
107
 
106
108
  rubyforge_project: csv-mapper
107
- rubygems_version: 1.3.1
109
+ rubygems_version: 1.3.4
108
110
  signing_key:
109
- specification_version: 2
110
- summary: CsvMapper is a small library intended to simplify the common steps involved with importing CSV files to a usable form in Ruby.
111
+ specification_version: 3
112
+ summary: CsvMapper is a small library intended to simplify the common steps involved with importing CSV files to a usable form in Ruby
111
113
  test_files:
112
114
  - test/test_csv-mapper.rb
113
115
  - test/test_helper.rb