csv-mapper 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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