Class: ActiveWarehouse::Cube
- Inherits:
-
Object
- Object
- ActiveWarehouse::Cube
- 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
-
.aggregates ⇒ Object
Get the aggregate classes for this dimension.
-
.class_name(name) ⇒ Object
Get the class name for the specified cube name Example: Regional Sales will become RegionalSalesCube.
-
.dimension_classes ⇒ Object
Get a list of dimension class instances.
-
.dimensions ⇒ Object
Get the dimensions that this cube pivots on.
-
.fact ⇒ Object
Get the fact that this cube reports on.
-
.fact_class ⇒ Object
Get the aggregated fact class instance.
-
.fact_class_name ⇒ Object
Get the aggregated fact class name.
-
.inherited(subclass) ⇒ Object
Callback which is invoked when subclasses are created.
- .last_modified ⇒ Object
- .logger ⇒ Object
-
.pivots_on(*dimension_list) ⇒ Object
(also: pivot_on)
Defines the dimensions that this cube pivots on.
-
.populate(options = {}) ⇒ Object
Populate all aggregates.
-
.rebuild(options = {}) ⇒ Object
Rebuild all aggregate classes.
-
.reports_on(fact) ⇒ Object
(also: report_on)
Defines the fact that this cube reports on.
-
.subclasses ⇒ Object
Get a list of all known subclasses.
Instance Method Summary collapse
Class Method Details
.aggregates ⇒ Object
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_classes ⇒ Object
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 |
.dimensions ⇒ Object
Get the dimensions that this cube pivots on
56 57 58 |
# File 'lib/active_warehouse/cube.rb', line 56 def dimensions @dimensions ||= [] end |
.fact ⇒ Object
Get the fact that this cube reports on
51 52 53 |
# File 'lib/active_warehouse/cube.rb', line 51 def fact @fact end |
.fact_class ⇒ Object
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_name ⇒ Object
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_modified ⇒ Object
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 |
.logger ⇒ Object
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(={}) [:force] ||= false aggregates.each do |agg_id, agg_clazz| if agg_clazz.needs_rebuild? || [: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(={}) logger.debug "Rebuilding aggregates for cube #{name}" [:force] ||= false build_aggregate_classes() 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 |
.subclasses ⇒ Object
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 = self.class.fact_class. #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| = [calculated_field] data_array << [: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 |