Class: ActiveWarehouse::Cube

Inherits:
Object
  • Object
show all
Defined in:
lib/active_warehouse/cube.rb

Overview

A Cube represents a collection of dimensions operating on a fact. The Cube provides a front-end for getting at the underlying data. The Cube manages the creation and population of all underlying aggregates.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.aggregatesObject

Get the aggregate classes for this dimension



61
62
63
64
# File 'lib/active_warehouse/cube.rb', line 61

def aggregates
  rebuild if @aggregates.nil?
  @aggregates
end

.class_name(name) ⇒ Object

Get the class name for the specified cube name Example: Regional Sales will become RegionalSalesCube



68
69
70
71
72
# File 'lib/active_warehouse/cube.rb', line 68

def class_name(name)
  cube_name = name.to_s
  cube_name = "#{cube_name}_cube" unless cube_name =~ /_cube$/
  cube_name.classify
end

.dimension_classesObject

Get a list of dimension class instances



85
86
87
# File 'lib/active_warehouse/cube.rb', line 85

def dimension_classes
  dimensions.collect {|dimension| Dimension.class_name(dimension).constantize} 
end

.dimensionsObject

Get the dimensions that this cube pivots on



56
57
58
# File 'lib/active_warehouse/cube.rb', line 56

def dimensions
  @dimensions ||= []
end

.factObject

Get the fact that this cube reports on



51
52
53
# File 'lib/active_warehouse/cube.rb', line 51

def fact
  @fact
end

.fact_classObject

Get the aggregated fact class instance



80
81
82
# File 'lib/active_warehouse/cube.rb', line 80

def fact_class
  fact_class_name.constantize
end

.fact_class_nameObject

Get the aggregated fact class name



75
76
77
# File 'lib/active_warehouse/cube.rb', line 75

def fact_class_name
  Fact.class_name(fact)
end

.inherited(subclass) ⇒ Object

Callback which is invoked when subclasses are created



7
8
9
# File 'lib/active_warehouse/cube.rb', line 7

def inherited(subclass)
  subclasses << subclass
end

.last_modifiedObject



93
94
95
96
97
98
99
100
# File 'lib/active_warehouse/cube.rb', line 93

def last_modified
  lm = Fact.class_for_name(fact).last_modified
  dimensions.each do |dimension|
    dim = Dimension.class_for_name(dimension)
    lm = dim.last_modified if dim.last_modified > lm
  end
  lm
end

.loggerObject



89
90
91
# File 'lib/active_warehouse/cube.rb', line 89

def logger
  @logger ||= Logger.new('cube.log')
end

.pivots_on(*dimension_list) ⇒ Object Also known as: pivot_on

Defines the dimensions that this cube pivots on.



17
18
19
20
21
22
# File 'lib/active_warehouse/cube.rb', line 17

def pivots_on(*dimension_list)
  # TODO: Validate if the fact is set
  dimension_list.each do |dimension|
    dimensions << dimension
  end
end

.populate(options = {}) ⇒ Object

Populate all aggregates. Set :force => true to force the population of the aggregate class.



40
41
42
43
44
45
46
47
48
# File 'lib/active_warehouse/cube.rb', line 40

def populate(options={})
  options[:force] ||= false
  aggregates.each do |agg_id, agg_clazz|
    if agg_clazz.needs_rebuild? || options[:force]
      logger.debug "Populating aggregate class #{agg_clazz.name}"
      agg_clazz.populate
    end
  end
end

.rebuild(options = {}) ⇒ Object

Rebuild all aggregate classes. Set :force => true to force the rebuild of aggregate classes.



33
34
35
36
37
# File 'lib/active_warehouse/cube.rb', line 33

def rebuild(options={})
  logger.debug "Rebuilding aggregates for cube #{name}"
  options[:force] ||= false
  build_aggregate_classes(options)
end

.reports_on(fact) ⇒ Object Also known as: report_on

Defines the fact that this cube reports on



26
27
28
29
# File 'lib/active_warehouse/cube.rb', line 26

def reports_on(fact)
  # TODO: Validate if one or more dimension is set
  @fact = fact
end

.subclassesObject

Get a list of all known subclasses



12
13
14
# File 'lib/active_warehouse/cube.rb', line 12

def subclasses
  @subclasses ||= []
end

Instance Method Details

#aggregate_map(column_dimension, column_hierarchy, row_dimension, row_hierarchy, cstage = 0, rstage = 0) ⇒ Object



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/active_warehouse/cube.rb', line 165

def aggregate_map(column_dimension, column_hierarchy, row_dimension, row_hierarchy, cstage=0, rstage=0)
  # Fill known cells
  agg_map = AggregateMap.new
  agg_records = nil
  # s = Benchmark.realtime do 
    agg_records = aggregate_records(column_dimension, column_hierarchy, cstage, row_dimension, row_hierarchy, rstage)
  #end
#       cs = 0
#       as = 0
#       calc = 0
#       x = 0
  calculated_fields = self.class.fact_class.calculated_fields
  calculated_field_options = self.class.fact_class.calculated_field_options
  #puts "loading aggregate_records took #{s}s"
  #s = Benchmark.realtime do
    #puts "there are #{agg_records.length} agg_records"
    #puts "there are #{self.class.fact_class.calculated_fields.length} calculated fields in class #{self.class.fact_class}"
    agg_records.each do |agg_record|
      # agg_record is an instance of Aggregate
      # collect the aggregate record data fields into an array
      data_array = nil
      #cs += Benchmark.realtime do
        data_array = agg_record.data_fields.collect{ |data_field_name| agg_record.send(data_field_name.to_sym) }
      #end
    
      # convert to an average where necessary
      # TODO: implement

      # add calculated fields to the data array
      #calc += Benchmark.realtime do
        calculated_fields.each do |calculated_field|
          options = calculated_field_options[calculated_field]
          data_array << options[:block].call(agg_record)
        end
      #end
    
      # add the data array to the aggregate map
      #as += Benchmark.realtime do
        agg_map.add_data(agg_record.dimension2_path, agg_record.dimension1_path, data_array)
      #end
    end
    
  #end
  #puts "creating the agg_map took #{s}s"
  #puts "total time spent collecting the data: #{cs}s, avg:#{cs/agg_records.length}s (#{(cs/s) * 100}%)"
  #puts "total time spent adding the data: #{as}s, avg:#{as/agg_records.length}s (#{(as/s) * 100}%)"
  #puts "total time spent calculating fields: #{calc}s, avg:#{calc/agg_records.length}s (#{(calc/s) * 100}%)"
  agg_map
end