public
Description: The purpose of gem parseline is to help the developers to load external CSV and fixed width files.
Homepage:
Clone URL: git://github.com/shairontoledo/parseline.git
Click here to lend your support to: parseline and make a donation at www.pledgie.com !
name age message
file README.rdoc Loading commit data...
directory lib/
file parseline.gemspec
README.rdoc

The purpose of gem parseline is to help the developers to load external CSV and fixed width files.

Installation

 sudo gem sources --add http://gems.github.com
 sudo gem install shairontoledo-parseline

or from rubyforge

 sudo gem install parseline

How to Use

A single data mapper

With ActiveRecord

Using CSV

You can use the files delimited by a character or using regexp. To demonstrate its we’ll use a migration/table

 class CreateProducts < ActiveRecord::Migration
  def self.up
    create_table :products do |t|
      t.integer :code
      t.string  :name
      t.boolean :in_stock
      t.date    :date
      t.float   :price
    end
  end

  def self.down
    drop_table :products
  end
 end

and a given file called ‘data.csv’ with the content below.

 1;PRODUT 1;Y;;11/21/2008;90.00
 2;PRODUT 2;N;;11/22/2008;341.33
 3;PRODUT 3;N;;11/01/2008;1.99
 4;PRODUT 4;Y;;11/15/2008;34.98
 5;PRODUT 5;N;;11/14/2008;130.44
 6;PRODUT 6;Y;;11/05/2008;20.11

The descriptions of data layout are

 product's code;name;if it is in stock;*reserved for future use*;date;price

As you can see we need format the column ‘in stock’ to boolean format and convert the date format from MM/DD/YYYY to YYYY-MM-DD. For every parse.field call, you receive the field to format using a lambda block.

so, take a look at the ActiveRecord definition using the module ParseLine::CSV

 require 'parseline'

 class Product < ActiveRecord::Base
   extend ParseLine::CSV
   csv_layout :delimiter => ";" do |parse|
     parse.field :code
     parse.field :name
     parse.ignore_field
     parse.field :in_stock, lambda {|s| s == 'Y' }
     parse.field :date ,    lambda {|d| d.gsub(/(\d{2})\/(\d{2})\/(\d{4})/,'\3-\1-\2') }
     parse.field :price
   end
 end

Each column will be mapped into a field, except the column after :name that is being ignored.

Loading external file

There are two ways that load data, by line use method Product.load_line to return an instance of Product

 data_file=File.readlines("data.csv")
 @product=Product.load_line data_file.first
 @product.save #data will go to database

or loading from file with all records returns an array of Products

 @products=Product.load_lines "data.csv"

Using Fixed Width

To load data with Fixed Width we need do a extend the module ParseLine::FixedWidth. It uses the same class methods to load data, the load_line and load_lines. See the file Fixed Width

 000001PRODUT  1       Y 11/21/2008000090.00
 000002PRODUT  2       N 11/22/2008000341.33
 000003PRODUT  3       N 11/01/2008000001.99
 000004PRODUT  4       Y 11/15/2008000034.98
 000005PRODUT  5       N 11/14/2008000130.44
 000006PRODUT  6       Y 11/05/2008000020.11

let’s split those lines and define a model like

 require 'parseline'

 class Product < ActiveRecord::Base
   extend ParseLine::FixedWidth
   fixed_width_layout do |parse|
     parse.field :code , 0..5
     parse.field :name,  6..21
     parse.field :in_stock, 22..22, lambda {|s| s == 'Y' }
     parse.field :date , 24..33,    lambda {|d| d.gsub(/(\d{2})\/(\d{2})\/(\d{4})/,'\3-\1-\2') }
     parse.field :price, 34..42
   end
 end

After that

  @products=Product.load_lines "data.txt"

With whatever class

Using Fixed Width

 require 'rubygems'
 require 'parseline'

 class Person

   attr_accessor :id
   attr_accessor :age

   extend ParseLine::FixedWidth

   fixed_width_layout do |parse|
     parse.field :id, 0..4
     parse.field :age, 5..6
   end
 end

After that

 @people=Person.load_lines "data.txt"

and

 @people.each{|person| p "id=#{person.id} and age=#{person.age}" }

Remember to use the parse module It’s easy to do, so enjoy and make money with it!