activewarehouse 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. data/README +62 -17
  2. data/Rakefile +17 -0
  3. data/generators/bridge/USAGE +1 -0
  4. data/generators/bridge/bridge_generator.rb +46 -0
  5. data/generators/bridge/templates/fixture.yml +5 -0
  6. data/generators/bridge/templates/migration.rb +20 -0
  7. data/generators/bridge/templates/model.rb +3 -0
  8. data/generators/dimension/templates/unit_test.rb +0 -2
  9. data/generators/dimension_view/USAGE +1 -0
  10. data/generators/dimension_view/dimension_view_generator.rb +62 -0
  11. data/generators/dimension_view/templates/migration.rb +11 -0
  12. data/generators/dimension_view/templates/model.rb +3 -0
  13. data/generators/dimension_view/templates/unit_test.rb +10 -0
  14. data/init.rb +1 -0
  15. data/lib/active_warehouse.rb +24 -9
  16. data/lib/active_warehouse/{model/aggregate.rb → aggregate.rb} +29 -13
  17. data/lib/active_warehouse/builder/date_dimension_builder.rb +21 -6
  18. data/lib/active_warehouse/builder/random_data_builder.rb +204 -3
  19. data/lib/active_warehouse/compat/compat.rb +49 -0
  20. data/lib/active_warehouse/{model/cube.rb → cube.rb} +47 -17
  21. data/lib/active_warehouse/dimension.rb +296 -0
  22. data/lib/active_warehouse/dimension/bridge.rb +15 -0
  23. data/lib/active_warehouse/dimension/dimension_view.rb +11 -0
  24. data/lib/active_warehouse/dimension/hierarchical_dimension.rb +60 -0
  25. data/lib/active_warehouse/dimension/slowly_changing_dimension.rb +137 -0
  26. data/lib/active_warehouse/{model/fact.rb → fact.rb} +45 -10
  27. data/lib/active_warehouse/migrations.rb +1 -2
  28. data/lib/active_warehouse/report.rb +3 -0
  29. data/lib/active_warehouse/{model/report → report}/abstract_report.rb +0 -0
  30. data/lib/active_warehouse/{model/report → report}/chart_report.rb +0 -0
  31. data/lib/active_warehouse/{model/report → report}/table_report.rb +0 -0
  32. data/lib/active_warehouse/version.rb +2 -2
  33. data/lib/active_warehouse/view/report_helper.rb +2 -1
  34. data/tasks/active_warehouse_tasks.rake +54 -0
  35. metadata +43 -21
  36. data/doc/agg_queries.txt +0 -26
  37. data/doc/agg_queries_results.txt +0 -150
  38. data/doc/queries.txt +0 -35
  39. data/lib/active_warehouse/model.rb +0 -5
  40. data/lib/active_warehouse/model/dimension.rb +0 -3
  41. data/lib/active_warehouse/model/dimension/bridge.rb +0 -32
  42. data/lib/active_warehouse/model/dimension/dimension.rb +0 -152
  43. data/lib/active_warehouse/model/dimension/hierarchical_dimension.rb +0 -35
  44. data/lib/active_warehouse/model/report.rb +0 -3
@@ -0,0 +1,15 @@
1
+ module ActiveWarehouse #:nodoc
2
+ # Implements a bridge table.
3
+ class Bridge < ActiveRecord::Base
4
+ class << self
5
+ # Get the table name. By default the table name will be the name of the bridge in singular form.
6
+ #
7
+ # Example: DepartmentHierarchyBridge will have a table called department_hierarchy_bridge
8
+ def table_name
9
+ name = self.name.demodulize.underscore
10
+ set_table_name(name)
11
+ name
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ module ActiveWarehouse #:nodoc
2
+ # DimensionViews represent role-playing dimensions in a data warehouse. These types of dimensions provide
3
+ # a view for an existing dimension. A common use is to provide a date dimension and then provide numerous
4
+ # role-playing dimensions implemented as views to the date dimension, such as Order Date Dimension,
5
+ # Shipping Date Dimension, etc.
6
+ class DimensionView < ActiveRecord::Base
7
+ class << self
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,60 @@
1
+ module ActiveWarehouse #:nodoc
2
+ # Implements a hierarchical dimension. Including the <tt>acts_as_hierarchical_dimension</tt> directive in
3
+ # a dimension will add methods for accessing the parent and children of any node in the hierarchy.
4
+ module HierarchicalDimension
5
+ def self.included(base) #:nodoc
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods #:nodoc
10
+ # Indicates that a dimension is a variable-depth hierarchy.
11
+ def acts_as_hierarchy_dimension
12
+ unless hierarchical_dimension?
13
+ class << self
14
+ # Get the bridge class for this dimension
15
+ def bridge_class
16
+ unless @bridge_class
17
+ unless Object.const_defined?(bridge_class_name.to_sym)
18
+ Object.const_set(bridge_class_name.to_sym, Class.new(ActiveWarehouse::Bridge))
19
+ end
20
+ @bridge_class = Object.const_get(bridge_class_name.to_sym)
21
+ end
22
+ @bridge_class
23
+ end
24
+
25
+ # Get the bridge class name for this hierarchical dimension
26
+ def bridge_class_name
27
+ name.gsub(/Dimension$/, '') + 'HierarchyBridge'
28
+ end
29
+ end
30
+ end
31
+ include InstanceMethods
32
+ end
33
+ alias :acts_as_hierarchical_dimension :acts_as_hierarchy_dimension
34
+
35
+ # Return true if this is a hierarchical dimension
36
+ def hierarchical_dimension?
37
+ self.included_modules.include?(InstanceMethods)
38
+ end
39
+ end
40
+
41
+ module InstanceMethods #:nodoc
42
+ # Get the parent for this node
43
+ def parent
44
+ self.class.find(:first,
45
+ :select => "a.*",
46
+ :joins => "a join #{self.class.bridge_class.table_name} b on a.id = b.parent_id",
47
+ :conditions => ['b.child_id = ? and b.levels_from_parent = 1', self.id])
48
+ end
49
+
50
+ # Get the children for this node
51
+ def children
52
+ self.class.find(:all,
53
+ :select => "a.*",
54
+ :joins => "a join #{self.class.bridge_class.table_name} b on a.id = b.child_id",
55
+ :conditions => ['b.parent_id = ? and b.levels_from_parent = 1', self.id])
56
+ end
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,137 @@
1
+ module ActiveWarehouse #:nodoc:
2
+ # Implements Type 2 Slowly Changing Dimensions.
3
+ #
4
+ # In a type 2 SCD, a new row is added each time a dimension entry requires an update. Three columns are required in
5
+ # the dimension table to support this:
6
+ #
7
+ # * latest_version - A boolean flag which indicates whether or not the row is the latest and current value
8
+ # * effective_date - A start date for when this row takes effect
9
+ # * expiration_date - An end date for when this row expires
10
+ #
11
+ # This module will override finder behavior in several ways. If used in a normal fashion, the find method will return
12
+ # the match row or rows with the latest_version flag set to true. You can also call the finder with the :valid_on
13
+ # option set indicating that you want the row that is valid on the given date.
14
+ #
15
+ # You can completely override the modified finder behavior using the :with_older option (set to true). You *must* include
16
+ # this option if you want to search for records which are not current (for example, using the find(id) version of the finder
17
+ # methods).
18
+ module SlowlyChangingDimension
19
+ def self.included(base) # :nodoc:
20
+ base.extend ClassMethods
21
+ end
22
+
23
+ module ClassMethods
24
+ # Indicate that the dimension is a Type 2 Slowly Changing Dimension (SDC).
25
+ #
26
+ # A word of warning:
27
+ #
28
+ # The expiration_date field must never be null. For the current effective record use the maximum date allowed.
29
+ # This is necessary because the find query used when :valid_on is specified is implemented using a between clause.
30
+ #
31
+ # Options:
32
+ # *<tt>:identifier</tt>:
33
+ # *<tt>:lastest_version</tt>: Define the attribute name which represents the latest version flag
34
+ # *<tt>:effective_date</tt>: Define the attribute name which represents the effective date column
35
+ # *<tt>:expiration_date</tt>: Define the attribute name which represents the expiration date column
36
+ #
37
+ def acts_as_slowly_changing_dimension(options = {})
38
+ unless slowly_changing_dimension? # don't let AR call this twice
39
+ cattr_accessor :identifier
40
+ cattr_accessor :latest_version_attribute
41
+ cattr_accessor :effective_date_attribute
42
+ cattr_accessor :expiration_date_attribute
43
+ self.identifier = options[:identifier] || :identifier
44
+ self.latest_version_attribute = options[:with] || :latest_version
45
+ self.effective_date_attribute = options[:effective_date_attribute] || :effective_date
46
+ self.expiration_date_attribute = options[:expiration_date_attribute] || :expiration_date
47
+ class << self
48
+ alias_method :find_every_with_older, :find_every
49
+ alias_method :calculate_with_older, :calculate
50
+ alias_method :core_validate_find_options, :validate_find_options
51
+ VALID_FIND_OPTIONS << :with_older
52
+ VALID_FIND_OPTIONS << :valid_on
53
+ VALID_FIND_OPTIONS << :valid_on_or_after
54
+ end
55
+ end
56
+ include InstanceMethods
57
+ end
58
+
59
+ # Return true if this dimension is a slowly changing dimension
60
+ def slowly_changing_dimension?
61
+ self.included_modules.include?(InstanceMethods)
62
+ end
63
+ end
64
+
65
+ module InstanceMethods #:nodoc:
66
+ def self.included(base) # :nodoc:
67
+ base.extend ClassMethods
68
+ end
69
+
70
+ def versions
71
+ self.class.find(:all,
72
+ :conditions => ["#{self.class.identifier} = ?", self.send(identifier)],
73
+ :with_older => true,
74
+ :order => "#{self.class.effective_date_attribute} asc")
75
+ end
76
+
77
+ module ClassMethods
78
+ def find_with_older(*args)
79
+ options = extract_options_from_args!(args)
80
+ validate_find_options(options)
81
+ set_readonly_option!(options)
82
+ options[:with_older] = true # yuck!
83
+
84
+ case args.first
85
+ when :first then find_initial(options)
86
+ when :all then find_every(options)
87
+ else find_from_ids(args, options)
88
+ end
89
+ end
90
+
91
+ def count_with_older(*args)
92
+ calculate_with_older(:count, *construct_count_options_from_legacy_args(*args))
93
+ end
94
+
95
+ def count(*args)
96
+ with_older_scope { count_with_older(*args) }
97
+ end
98
+
99
+ def calculate(*args)
100
+ with_older_scope { calculate_with_older(*args) }
101
+ end
102
+
103
+ protected
104
+ def with_older_scope(&block)
105
+ with_scope({:find => { :conditions =>
106
+ "#{table_name}.#{latest_version_attribute} = 1" } }, :merge, &block)
107
+ end
108
+
109
+ def with_valid_on_scope(valid_on, &block)
110
+ with_scope({:find => { :conditions =>
111
+ ["? between #{effective_date_attribute} " +
112
+ "and #{expiration_date_attribute}", valid_on]} }, :merge, &block)
113
+ end
114
+
115
+ def with_valid_on_or_after_scope(valid_on_or_after, &block)
116
+ with_scope({:find => {:conditions =>
117
+ ["#{effective_date_attribute} <= ? and #{expiration_date_attribute} > ?",
118
+ valid_on_or_after, valid_on_or_after]} }, :merge, &block)
119
+ end
120
+
121
+ private
122
+ # all find calls lead here
123
+ def find_every(options)
124
+ if options.include?(:valid_on)
125
+ with_valid_on_scope(options[:valid_on]) { find_every_with_older(options) }
126
+ elsif options.include?(:valid_on_or_after)
127
+ with_valid_on_or_after_scope(options[:valid_on_or_after]) { find_every_with_older(options) }
128
+ elsif options.include?(:with_older)
129
+ find_every_with_older(options)
130
+ else
131
+ with_older_scope { find_every_with_older(options) }
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
@@ -1,28 +1,56 @@
1
- module ActiveWarehouse
1
+ module ActiveWarehouse #:nodoc
2
+ # Facts represent business measures. A row in a fact table corresponds to set of measurements in a particular
3
+ # granularity along with the foreign keys connecting the fact to various dimensions. All measurements in a fact
4
+ # table must be at the same grain.
2
5
  class Fact < ActiveRecord::Base
3
-
4
6
  class << self
5
- attr_accessor :aggregate_fields, :aggregate_field_options, :calculated_fields, :calculated_field_options
7
+ # Array of aggregate field names
8
+ attr_accessor :aggregate_fields
9
+
10
+ # Hash of aggregate field options, where the key is the field name
11
+ # and the value is the Hash of options for that aggregate.
12
+ attr_accessor :aggregate_field_options
13
+
14
+ # Array of calculated field names
15
+ attr_accessor :calculated_fields
16
+
17
+ # Hash of calculated field options, where the key is the field name
18
+ # and the value is the Hash of options for that calculated field.
19
+ attr_accessor :calculated_field_options
6
20
 
7
21
  # Return a list of dimensions for this fact.
8
22
  #
9
23
  # Example:
10
24
  #
11
25
  # sales_fact
12
- # time_id
26
+ # date_id
13
27
  # region_id
14
28
  # sales_amount
15
29
  # number_items_sold
16
30
  #
17
- # Calling SalesFact.dimensions would return the list: ['time','region']
31
+ # Calling SalesFact.dimensions would return the list: [:date, :region]
18
32
  def dimensions
19
- dims = []
33
+ foreign_key_columns.collect { |c| c.name.gsub(/_id/, '').to_sym }
34
+ end
35
+
36
+ # Get all of the Column objects representing foreign key columns
37
+ #
38
+ # Example:
39
+ #
40
+ # sales_fact
41
+ # date_id
42
+ # region_id
43
+ # sales_amount
44
+ # number_items_sold
45
+ #
46
+ # Calling SalesFact.foreign_key_columns would return a list of column objects containing
47
+ # the date column and the region column.
48
+ def foreign_key_columns
49
+ fk_columns = []
20
50
  columns.each do |column|
21
- if column.name =~ /(.*)_id/
22
- dims << $1.to_sym
23
- end
51
+ fk_columns << column if column.name =~ /(.*)_id/
24
52
  end
25
- dims
53
+ fk_columns
26
54
  end
27
55
 
28
56
  # Get the time when the fact source file was last modified
@@ -49,6 +77,13 @@ module ActiveWarehouse
49
77
  class_name(name).constantize
50
78
  end
51
79
 
80
+ # Get the fact class for the specified value. The fact parameter may be a class,
81
+ # String or Symbol.
82
+ def to_fact(dimension)
83
+ return dimension if dimension.is_a?(Class) and dimension.superclass == Fact
84
+ return class_for_name(dimension)
85
+ end
86
+
52
87
  # Define an aggregate. Also aliased from aggregate()
53
88
  # * <tt>field</tt>: The field name
54
89
  # * <tt>options</tt>: A hash of options for the aggregate
@@ -1,7 +1,6 @@
1
1
  module ActiveWarehouse #:nodoc:
2
- # Responsible for migrating ActiveWarehouse
2
+ # Responsible for migrating ActiveWarehouse tables which are automatically created.
3
3
  class Migrator < ActiveRecord::Migrator
4
-
5
4
  class << self
6
5
  def schema_info_table_name #:nodoc:
7
6
  ActiveRecord::Base.table_name_prefix + 'activewarehouse_schema_info' + ActiveRecord::Base.table_name_suffix
@@ -0,0 +1,3 @@
1
+ require 'active_warehouse/report/abstract_report'
2
+ require 'active_warehouse/report/table_report'
3
+ require 'active_warehouse/report/chart_report'
@@ -1,7 +1,7 @@
1
- module ActiveWarehouse
1
+ module ActiveWarehouse #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
- MINOR = 1
4
+ MINOR = 2
5
5
  TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
@@ -138,6 +138,7 @@ module ReportHelper
138
138
  end
139
139
  end
140
140
 
141
+ # TODO: implement chart rendering
141
142
  def render_chart_report(report, html_options)
142
143
  "Not Yet Implemented"
143
144
  end
@@ -190,7 +191,7 @@ module ReportHelper
190
191
  # Example:
191
192
  # sortable_column_header('SSN','ssn')
192
193
  # sortable_column_header('Name','name',{:onclick => 'doSomething();'}, {:title => 'Some Title'})
193
- def sortable_column_header(column_name, order_by, link_parameters={}, attributes={})
194
+ def sortable_column_header(column_name, order_by, link_parameters={}, attributes={}) # TODO get this thing back into the mix
194
195
  order = 'desc'
195
196
  if params[:order_by].to_s == order_by.to_s
196
197
  sorted = 'sorted'
@@ -1,4 +1,13 @@
1
1
  namespace :warehouse do
2
+ desc "Drop and create the current database"
3
+ task :recreate => :environment do
4
+ abcs = ActiveRecord::Base.configurations
5
+ ActiveRecord::Base.establish_connection(abcs[RAILS_ENV])
6
+ puts "Recreating #{ActiveRecord::Base.connection.current_database}"
7
+ ActiveRecord::Base.connection.recreate_database(ActiveRecord::Base.connection.current_database)
8
+ ActiveRecord::Base.connection.reconnect!
9
+ end
10
+
2
11
  desc "Build a 'standard' date dimension"
3
12
  task :build_date_dimension => :environment do
4
13
  abcs = ActiveRecord::Base.configurations
@@ -6,6 +15,8 @@ namespace :warehouse do
6
15
 
7
16
  start_date = (ENV['START_DATE'] ? Time.parse(ENV['START_DATE']) : Time.now.years_ago(5))
8
17
  end_date = (ENV['END_DATE'] ? Time.parse(ENV['END_DATE']) : Time.now )
18
+
19
+ puts "Building date dimension"
9
20
 
10
21
  ddb = ActiveWarehouse::Builder::DateDimensionBuilder.new(start_date, end_date)
11
22
  ddb.build.each do |record|
@@ -17,6 +28,34 @@ namespace :warehouse do
17
28
  end
18
29
  end
19
30
 
31
+ desc "Build random data for all facts and dimensions in the models directory, excluding date"
32
+ task :build_random_data => :environment do
33
+ abcs = ActiveRecord::Base.configurations
34
+ ActiveRecord::Base.establish_connection(abcs[RAILS_ENV])
35
+ require 'pp'
36
+
37
+ truncate = true if ENV['TRUNCATE']
38
+ name = ENV['NAME']
39
+
40
+ if name
41
+ build_and_load(name, truncate)
42
+ else
43
+ models_dir = File.join(File.dirname(__FILE__), '../../../../app/models')
44
+ Dir.glob(File.join(models_dir, "**", "*.rb")).each do |f|
45
+ name = File.basename(f, '.rb')
46
+ next unless name =~ /_dimension$|_fact$/
47
+ next if name == 'date_dimension'
48
+ build_and_load(name)
49
+ end
50
+ end
51
+ end
52
+
53
+ desc "Populate with test data"
54
+ task :populate => [:build_date_dimension, :build_random_data]
55
+
56
+ desc "Recreate, migrate and populate"
57
+ task :setup => [:recreate, :migrate, 'db:migrate', :populate]
58
+
20
59
  desc "Rebuild the warehouse" # TODO: consider moving this logic somewhere into a class and calling it from here
21
60
  task :rebuild => :environment do
22
61
  puts "Rebuilding data warehouse"
@@ -47,4 +86,19 @@ namespace :warehouse do
47
86
  migration_directory = File.join(File.dirname(__FILE__), '../db/migrations')
48
87
  ActiveWarehouse::Migrator.migrate(migration_directory, ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
49
88
  end
89
+ end
90
+
91
+ def build_and_load(name, truncate=false)
92
+ builder = ActiveWarehouse::Builder::RandomDataBuilder.new
93
+ puts "Building #{name}"
94
+ clazz = name.classify.constantize
95
+ if truncate # TODO: Handle through adapter by adding a truncate method to the adapter
96
+ clazz.connection.execute("TRUNCATE #{clazz.table_name}")
97
+ end
98
+ options = {:fk_limit => {'date_id' => DateDimension.count}}
99
+ builder.build(name, options).each do |record|
100
+ clazz.create(record)
101
+ end
102
+ rescue => e
103
+ puts "Unable to build #{name}: #{e}"
50
104
  end
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.0
2
+ rubygems_version: 0.9.0.10
3
3
  specification_version: 1
4
4
  name: activewarehouse
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.0
7
- date: 2006-12-19 00:00:00 -05:00
6
+ version: 0.2.0
7
+ date: 2007-02-18 00:00:00 -05:00
8
8
  summary: Build data warehouses with Rails.
9
9
  require_paths:
10
10
  - lib
@@ -29,18 +29,24 @@ post_install_message:
29
29
  authors:
30
30
  - Anthony Eden
31
31
  files:
32
+ - init.rb
32
33
  - install.rb
33
34
  - README
34
35
  - TODO
35
36
  - Rakefile
36
37
  - db/migrations
37
38
  - db/migrations/001_create_table_reports.rb
38
- - doc/agg_queries.txt
39
- - doc/agg_queries_results.txt
40
- - doc/queries.txt
39
+ - generators/bridge
41
40
  - generators/cube
42
41
  - generators/dimension
42
+ - generators/dimension_view
43
43
  - generators/fact
44
+ - generators/bridge/bridge_generator.rb
45
+ - generators/bridge/templates
46
+ - generators/bridge/USAGE
47
+ - generators/bridge/templates/fixture.yml
48
+ - generators/bridge/templates/migration.rb
49
+ - generators/bridge/templates/model.rb
44
50
  - generators/cube/cube_generator.rb
45
51
  - generators/cube/templates
46
52
  - generators/cube/USAGE
@@ -53,6 +59,12 @@ files:
53
59
  - generators/dimension/templates/migration.rb
54
60
  - generators/dimension/templates/model.rb
55
61
  - generators/dimension/templates/unit_test.rb
62
+ - generators/dimension_view/dimension_view_generator.rb
63
+ - generators/dimension_view/templates
64
+ - generators/dimension_view/USAGE
65
+ - generators/dimension_view/templates/migration.rb
66
+ - generators/dimension_view/templates/model.rb
67
+ - generators/dimension_view/templates/unit_test.rb
56
68
  - generators/fact/fact_generator.rb
57
69
  - generators/fact/templates
58
70
  - generators/fact/USAGE
@@ -62,34 +74,35 @@ files:
62
74
  - generators/fact/templates/unit_test.rb
63
75
  - lib/active_warehouse
64
76
  - lib/active_warehouse.rb
77
+ - lib/active_warehouse/aggregate.rb
65
78
  - lib/active_warehouse/builder
66
79
  - lib/active_warehouse/builder.rb
80
+ - lib/active_warehouse/compat
67
81
  - lib/active_warehouse/core_ext
68
82
  - lib/active_warehouse/core_ext.rb
83
+ - lib/active_warehouse/cube.rb
84
+ - lib/active_warehouse/dimension
85
+ - lib/active_warehouse/dimension.rb
86
+ - lib/active_warehouse/fact.rb
69
87
  - lib/active_warehouse/migrations.rb
70
- - lib/active_warehouse/model
71
- - lib/active_warehouse/model.rb
88
+ - lib/active_warehouse/report
89
+ - lib/active_warehouse/report.rb
72
90
  - lib/active_warehouse/version.rb
73
91
  - lib/active_warehouse/view
74
92
  - lib/active_warehouse/view.rb
75
93
  - lib/active_warehouse/builder/date_dimension_builder.rb
76
94
  - lib/active_warehouse/builder/random_data_builder.rb
95
+ - lib/active_warehouse/compat/compat.rb
77
96
  - lib/active_warehouse/core_ext/time
78
97
  - lib/active_warehouse/core_ext/time.rb
79
98
  - lib/active_warehouse/core_ext/time/calculations.rb
80
- - lib/active_warehouse/model/aggregate.rb
81
- - lib/active_warehouse/model/cube.rb
82
- - lib/active_warehouse/model/dimension
83
- - lib/active_warehouse/model/dimension.rb
84
- - lib/active_warehouse/model/fact.rb
85
- - lib/active_warehouse/model/report
86
- - lib/active_warehouse/model/report.rb
87
- - lib/active_warehouse/model/dimension/bridge.rb
88
- - lib/active_warehouse/model/dimension/dimension.rb
89
- - lib/active_warehouse/model/dimension/hierarchical_dimension.rb
90
- - lib/active_warehouse/model/report/abstract_report.rb
91
- - lib/active_warehouse/model/report/chart_report.rb
92
- - lib/active_warehouse/model/report/table_report.rb
99
+ - lib/active_warehouse/dimension/bridge.rb
100
+ - lib/active_warehouse/dimension/dimension_view.rb
101
+ - lib/active_warehouse/dimension/hierarchical_dimension.rb
102
+ - lib/active_warehouse/dimension/slowly_changing_dimension.rb
103
+ - lib/active_warehouse/report/abstract_report.rb
104
+ - lib/active_warehouse/report/chart_report.rb
105
+ - lib/active_warehouse/report/table_report.rb
93
106
  - lib/active_warehouse/view/report_helper.rb
94
107
  - tasks/active_warehouse_tasks.rake
95
108
  test_files: []
@@ -142,3 +155,12 @@ dependencies:
142
155
  - !ruby/object:Gem::Version
143
156
  version: 1.12.5.5618
144
157
  version:
158
+ - !ruby/object:Gem::Dependency
159
+ name: rails_sql_views
160
+ version_requirement:
161
+ version_requirements: !ruby/object:Gem::Version::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: 0.1.0
166
+ version: