Class: Ruport::DataSet

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/ruport/data_set.rb

Overview

The DataSet is the core datastructure for Ruport. It provides methods that allow you to compare and combine query results, data loaded in from CSVs, and user-defined sets of data.

It is tightly integrated with Ruport’s formatting and query systems, so if you’d like to take advantage of these models, you will probably find DataSet useful.

Sample Usage:

my_data = [[1,2,3],[4,5,6],[7,8,9]]

ds = Ruport::DataSet.new([:col1, :col2, :col3],my_data)
ds << [ 10, 11, 12]
ds << { :col3 => 15, :col1 => 13, :col2 => 14 }
puts ds.select_columns(:col1, :col3).to_csv

Output:

col1,col3
1,3
4,6
7,9
10,12
13,15

The wild and crazy might want to try the Array hack:

puts [[1,2,3],[4,5,6],[7,8,9]].to_ds(%w[col1 col2 col3])

Output:

fields: ( col1, col2, col3 )
row0: ( 1, 2, 3 )
row1: ( 4, 5, 6 )
row2: ( 7, 8, 9 )

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(fields = [], content = nil, default = nil) ⇒ DataSet

DataSets must be given a set of fields to be defined.

These field names will define the columns for the DataSet and how you access them.

data = Ruport::DataSet.new %w[ id name phone ]

You can optionally pass in some content as well. (Must be Enumerable)

content = [ %w[ a1 gregory 203-525-0523 ], 
            %w[ a2 james   555-555-5555 ] ]

data    = Ruport::DataSet.new(%w[ id name phone],content)


67
68
69
70
71
72
# File 'lib/ruport/data_set.rb', line 67

def initialize(fields=[], content=nil, default=nil)
  @fields = fields
  @data = []
  @default = default
  content.each { |r| self << r } if content
end

Instance Attribute Details

#dataObject (readonly)

data holds the elements of the Row



81
82
83
# File 'lib/ruport/data_set.rb', line 81

def data
  @data
end

#defaultObject

the default value to fill empty cells with



78
79
80
# File 'lib/ruport/data_set.rb', line 78

def default
  @default
end

#fieldsObject

an array which contains column names



75
76
77
# File 'lib/ruport/data_set.rb', line 75

def fields
  @fields
end

Class Method Details

.load(source, default = "") ⇒ Object

Allows loading of CSV files or YAML dumps. Returns a DataSet

FasterCSV will be used if it is installed.

my_data = Ruport::DataSet.load("foo.csv")
my_data = Ruport::DataSet.load("foo.yaml")
my_data = Ruport::DataSet.load("foo.yml")


142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/ruport/data_set.rb', line 142

def self.load ( source, default="")
  case source
  when /\.(yaml|yml)/
    return YAML.load(File.open(source))
  when /\.csv/ 
    csv_klass = defined?(FasterCSV) ? FasterCSV : CSV
    input = csv_klass.read(source) if source =~ /\.csv/
    loaded_data = self.new
    loaded_data.fields = input[0]
    loaded_data.default = default
    input[1..-1].each { |row| loaded_data << row }
    return loaded_data	
  else
    raise "Invalid file type"
  end
end

Instance Method Details

#<<(stuff, filler = @default) ⇒ Object

appends a row to the DataSet can be added as an array or a keyed hash-like object.

Columns left undefined will be filled with DataSet#default values.

data << [ 1, 2, 3 ]
data << { :some_field_name => 3, :other => 2, :another => 1 }


108
109
110
# File 'lib/ruport/data_set.rb', line 108

def << ( stuff, filler=@default )
  @data << DataRow.new(stuff,@fields,:filler => filler)
end

#==(data2) ⇒ Object

checks if one dataset equals another



126
127
128
# File 'lib/ruport/data_set.rb', line 126

def ==(data2)
  eql?(data2)
end

#[](index) ⇒ Object

Allows ordinal access to rows

my_data[2] -> Ruport::DataRow


91
92
93
# File 'lib/ruport/data_set.rb', line 91

def [](index)
  @data[index]
end

#[]=(index, value) ⇒ Object

allows setting of rows (providing a DataRow is passed in)



96
97
98
99
# File 'lib/ruport/data_set.rb', line 96

def []=(index,value)
  throw "Invalid object type" unless value.kind_of?(DataRow)
  @data[index] = value
end

#as(format, &action) ⇒ Object

uses Format::Builder to render DataSets in various ready to output formats.

data.as(:html)                  -> String

data.as(:text) do |builder|
  builder.range = 2..4          -> String
  builder.header = "My Title"
end

To add new formats to this function, simply re-open Format::Builder and add methods like render_my_format_name.

This will enable data.as(:my_format_name)



195
196
197
198
199
200
# File 'lib/ruport/data_set.rb', line 195

def as(format,&action)
  builder = Format::Builder.new( self )
  builder.format = format
  action.call(builder) if block_given?
  builder.render
end

#cloneObject

provides a deep copy of the DataSet.



84
85
86
# File 'lib/ruport/data_set.rb', line 84

def clone
  DataSet.new(@fields,@data)
end

#each(&action) ⇒ Object

Iterates through the rows, yielding a DataRow for each.



160
161
162
# File 'lib/ruport/data_set.rb', line 160

def each(&action)
  @data.each(&action)
end

#empty?Boolean

Returns true if DataSet contains no rows, false otherwise.

Returns:

  • (Boolean)


131
132
133
# File 'lib/ruport/data_set.rb', line 131

def empty?
  return @data.empty?
end

#eql?(data2) ⇒ Boolean

checks if one dataset equals another

Returns:

  • (Boolean)


113
114
115
116
117
118
119
120
121
122
123
# File 'lib/ruport/data_set.rb', line 113

def eql?(data2)
  return false unless ( @data.length == data2.data.length and
                        @fields.eql?(data2.fields) )
  @data.each_with_index do |row, r_index|
    row.each_with_index do |field, f_index|
      return false unless field.eql?(data2[r_index][f_index])
    end
  end

  return true
end

#remove_columns(*fields) ⇒ Object

Returns a new DataSet with the specified fields removed



171
172
173
# File 'lib/ruport/data_set.rb', line 171

def remove_columns(*fields)
  select_fields(*(@fields-fields))
end

#remove_columns!(*fields) ⇒ Object

removes the specified fields from this DataSet (DESTRUCTIVE!)



176
177
178
179
# File 'lib/ruport/data_set.rb', line 176

def remove_columns!(*fields)
  @fields -= fields
  @data = select_fields(*(@fields)).to_a
end

#select_columns(*fields) ⇒ Object

Returns a new DataSet composed of the fields specified.



165
166
167
168
# File 'lib/ruport/data_set.rb', line 165

def select_columns(*fields)
  rows = fields.inject([]) { |s,e| s << map { |row| row[e] } }.transpose
  my_data = DataSet.new(fields,rows)
end

#to_csvObject

Converts a DataSet to CSV



203
# File 'lib/ruport/data_set.rb', line 203

def to_csv; as(:csv) end

#to_htmlObject

Converts a Dataset to html



206
# File 'lib/ruport/data_set.rb', line 206

def to_html; as(:html) end

#to_sObject

Readable string representation of the DataSet



209
# File 'lib/ruport/data_set.rb', line 209

def to_s; as(:text) end