mainej-activewarehouse 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. data/activewarehouse/README +99 -0
  2. data/activewarehouse/Rakefile +165 -0
  3. data/activewarehouse/TODO +4 -0
  4. data/activewarehouse/db/migrations/001_create_table_reports.rb +28 -0
  5. data/activewarehouse/doc/references.txt +4 -0
  6. data/activewarehouse/generators/bridge/USAGE +1 -0
  7. data/activewarehouse/generators/bridge/bridge_generator.rb +46 -0
  8. data/activewarehouse/generators/bridge/templates/fixture.yml +5 -0
  9. data/activewarehouse/generators/bridge/templates/migration.rb +27 -0
  10. data/activewarehouse/generators/bridge/templates/model.rb +3 -0
  11. data/activewarehouse/generators/bridge/templates/unit_test.rb +8 -0
  12. data/activewarehouse/generators/cube/USAGE +1 -0
  13. data/activewarehouse/generators/cube/cube_generator.rb +28 -0
  14. data/activewarehouse/generators/cube/templates/model.rb +3 -0
  15. data/activewarehouse/generators/cube/templates/unit_test.rb +8 -0
  16. data/activewarehouse/generators/date_dimension/USAGE +1 -0
  17. data/activewarehouse/generators/date_dimension/date_dimension_generator.rb +16 -0
  18. data/activewarehouse/generators/date_dimension/templates/fixture.yml +5 -0
  19. data/activewarehouse/generators/date_dimension/templates/migration.rb +31 -0
  20. data/activewarehouse/generators/date_dimension/templates/model.rb +3 -0
  21. data/activewarehouse/generators/date_dimension/templates/unit_test.rb +8 -0
  22. data/activewarehouse/generators/dimension/USAGE +1 -0
  23. data/activewarehouse/generators/dimension/dimension_generator.rb +46 -0
  24. data/activewarehouse/generators/dimension/templates/fixture.yml +5 -0
  25. data/activewarehouse/generators/dimension/templates/migration.rb +11 -0
  26. data/activewarehouse/generators/dimension/templates/model.rb +3 -0
  27. data/activewarehouse/generators/dimension/templates/unit_test.rb +8 -0
  28. data/activewarehouse/generators/dimension_view/USAGE +1 -0
  29. data/activewarehouse/generators/dimension_view/dimension_view_generator.rb +62 -0
  30. data/activewarehouse/generators/dimension_view/templates/migration.rb +17 -0
  31. data/activewarehouse/generators/dimension_view/templates/model.rb +3 -0
  32. data/activewarehouse/generators/dimension_view/templates/unit_test.rb +10 -0
  33. data/activewarehouse/generators/fact/USAGE +1 -0
  34. data/activewarehouse/generators/fact/fact_generator.rb +46 -0
  35. data/activewarehouse/generators/fact/templates/fixture.yml +5 -0
  36. data/activewarehouse/generators/fact/templates/migration.rb +13 -0
  37. data/activewarehouse/generators/fact/templates/model.rb +3 -0
  38. data/activewarehouse/generators/fact/templates/unit_test.rb +10 -0
  39. data/activewarehouse/generators/time_dimension/USAGE +1 -0
  40. data/activewarehouse/generators/time_dimension/templates/fixture.yml +5 -0
  41. data/activewarehouse/generators/time_dimension/templates/migration.rb +12 -0
  42. data/activewarehouse/generators/time_dimension/templates/model.rb +3 -0
  43. data/activewarehouse/generators/time_dimension/templates/unit_test.rb +8 -0
  44. data/activewarehouse/generators/time_dimension/time_dimension_generator.rb +14 -0
  45. data/activewarehouse/init.rb +1 -0
  46. data/activewarehouse/install.rb +5 -0
  47. data/activewarehouse/lib/active_warehouse.rb +91 -0
  48. data/activewarehouse/lib/active_warehouse/aggregate.rb +75 -0
  49. data/activewarehouse/lib/active_warehouse/aggregate/dwarf_aggregate.rb +369 -0
  50. data/activewarehouse/lib/active_warehouse/aggregate/dwarf_common.rb +44 -0
  51. data/activewarehouse/lib/active_warehouse/aggregate/dwarf_printer.rb +34 -0
  52. data/activewarehouse/lib/active_warehouse/aggregate/no_aggregate.rb +212 -0
  53. data/activewarehouse/lib/active_warehouse/aggregate/pid_aggregate.rb +29 -0
  54. data/activewarehouse/lib/active_warehouse/aggregate_field.rb +59 -0
  55. data/activewarehouse/lib/active_warehouse/bridge.rb +19 -0
  56. data/activewarehouse/lib/active_warehouse/bridge/hierarchy_bridge.rb +46 -0
  57. data/activewarehouse/lib/active_warehouse/builder.rb +3 -0
  58. data/activewarehouse/lib/active_warehouse/builder/date_dimension_builder.rb +91 -0
  59. data/activewarehouse/lib/active_warehouse/builder/generator/generator.rb +13 -0
  60. data/activewarehouse/lib/active_warehouse/builder/generator/name_generator.rb +20 -0
  61. data/activewarehouse/lib/active_warehouse/builder/generator/paragraph_generator.rb +11 -0
  62. data/activewarehouse/lib/active_warehouse/builder/random_data_builder.rb +239 -0
  63. data/activewarehouse/lib/active_warehouse/builder/test_data_builder.rb +54 -0
  64. data/activewarehouse/lib/active_warehouse/calculated_field.rb +27 -0
  65. data/activewarehouse/lib/active_warehouse/compat/compat.rb +49 -0
  66. data/activewarehouse/lib/active_warehouse/core_ext.rb +1 -0
  67. data/activewarehouse/lib/active_warehouse/core_ext/time.rb +5 -0
  68. data/activewarehouse/lib/active_warehouse/core_ext/time/calculations.rb +40 -0
  69. data/activewarehouse/lib/active_warehouse/cube.rb +235 -0
  70. data/activewarehouse/lib/active_warehouse/cube_query_result.rb +69 -0
  71. data/activewarehouse/lib/active_warehouse/dimension.rb +329 -0
  72. data/activewarehouse/lib/active_warehouse/dimension/date_dimension.rb +15 -0
  73. data/activewarehouse/lib/active_warehouse/dimension/dimension_reflection.rb +21 -0
  74. data/activewarehouse/lib/active_warehouse/dimension/dimension_view.rb +27 -0
  75. data/activewarehouse/lib/active_warehouse/dimension/hierarchical_dimension.rb +99 -0
  76. data/activewarehouse/lib/active_warehouse/dimension/slowly_changing_dimension.rb +147 -0
  77. data/activewarehouse/lib/active_warehouse/fact.rb +239 -0
  78. data/activewarehouse/lib/active_warehouse/field.rb +74 -0
  79. data/activewarehouse/lib/active_warehouse/migrations.rb +64 -0
  80. data/activewarehouse/lib/active_warehouse/ordered_hash.rb +34 -0
  81. data/activewarehouse/lib/active_warehouse/prejoin_fact.rb +97 -0
  82. data/activewarehouse/lib/active_warehouse/report.rb +7 -0
  83. data/activewarehouse/lib/active_warehouse/report/abstract_report.rb +149 -0
  84. data/activewarehouse/lib/active_warehouse/report/chart_report.rb +9 -0
  85. data/activewarehouse/lib/active_warehouse/report/data_cell.rb +21 -0
  86. data/activewarehouse/lib/active_warehouse/report/data_column.rb +19 -0
  87. data/activewarehouse/lib/active_warehouse/report/data_row.rb +15 -0
  88. data/activewarehouse/lib/active_warehouse/report/dimension.rb +58 -0
  89. data/activewarehouse/lib/active_warehouse/report/table_report.rb +38 -0
  90. data/activewarehouse/lib/active_warehouse/version.rb +9 -0
  91. data/activewarehouse/lib/active_warehouse/view.rb +9 -0
  92. data/activewarehouse/lib/active_warehouse/view/crumb.rb +64 -0
  93. data/activewarehouse/lib/active_warehouse/view/report_helper.rb +98 -0
  94. data/activewarehouse/lib/active_warehouse/view/table_view.rb +134 -0
  95. data/activewarehouse/lib/active_warehouse/view/yui_adapter.rb +68 -0
  96. data/activewarehouse/tasks/active_warehouse_tasks.rake +122 -0
  97. metadata +237 -0
@@ -0,0 +1,99 @@
1
+ == ActiveWarehouse
2
+
3
+ The ActiveWarehouse library provides classes and functions which help with
4
+ building Data Warehouses using Rails. It can be installed either as a plugin
5
+ or as a Gem.
6
+
7
+ To install as a plugin just use:
8
+
9
+ script/plugin install --force svn://rubyforge.org/var/svn/activewarehouse/activewarehouse/trunk
10
+
11
+ To get the latest edge version.
12
+
13
+ To install as a Gem, use:
14
+
15
+ gem install activewarehouse
16
+
17
+ On *nix you will need to run this command as root or better yet, using sudo.
18
+
19
+ Next, you will need to freeze or link the Gem to your Rails app. I prefer using
20
+ the gemsonrails project:
21
+
22
+ gem install gemsonrails
23
+
24
+ And then in your Rails app:
25
+
26
+ rake gems:link GEM=activewarehouse
27
+
28
+ It is possible that freezing the Gem to the Rails app may not work at all times. It is most often best to install as a plugin.
29
+
30
+ == Generators
31
+
32
+ ActiveWarehouse comes with several generators
33
+
34
+ script/generate fact Sales
35
+ script/generate fact sales
36
+
37
+ Creates a SalesFact class and a sales_facts table.
38
+
39
+ script/generate dimension Region
40
+ script/generate dimension region
41
+
42
+ Creates a RegionDimension class and a region_dimension table.
43
+
44
+ script/generate cube RegionalSales
45
+ script/generate cube regional_sales
46
+
47
+ Creates a RegionalSalesCube class.
48
+
49
+ script/generate bridge CustomerHierarchy
50
+ script/generate bridge customer_hierarchy
51
+
52
+ Creates a CustomerHierarchyBridge class.
53
+
54
+ script/generate dimension_view OrderDate Date
55
+ script/generate dimension_view order_date date
56
+
57
+ Creates an OrderDateDimension class which is represented by a view on top
58
+ of the DateDimension.
59
+
60
+ The rules for naming are as follows:
61
+
62
+ Facts:
63
+ Fact classes and tables follow the typical Rails rules: classes are singular
64
+ and tables are pluralized.
65
+ Both the class and table name are suffixed by "_fact".
66
+ Dimensions:
67
+ Dimension classes and tables are both singular.
68
+ Both the class name and the table name are suffixed by "_dimension".
69
+ Cube:
70
+ Cube class is singular. If a cube table is created it will also be singular.
71
+ Bridge:
72
+ Bridge classes and tables are both singular.
73
+ Both the class name and the table name are suffixed by "_bridge".
74
+ Dimension View:
75
+ Dimension View classes are singular. The underlying data structure is a view
76
+ on top of an existing dimension.
77
+ Both the class name and the view name are suffixed by "_dimension"
78
+
79
+ == ETL
80
+
81
+ The ActiveWarehouse plugin does not directly handle Extract-Transform-Load
82
+ processes, however the ActiveWarehouse ETL gem (installed separately) can help.
83
+ To install it use:
84
+
85
+ gem install activewarehouse-etl
86
+
87
+ Once again you should run this command as root or using sudo.
88
+
89
+ More information on the ETL process can be found at
90
+ http://activewarehouse.rubyforge.org/etl
91
+
92
+ == Tutorial
93
+
94
+ A tutorial for ActiveWarehouse is available online at
95
+ http://anthonyeden.com/2006/12/20/activewarehouse-example-with-rails-svn-logs
96
+ (Note that is is out of date.)
97
+
98
+ You can also get a demo from the ActiveWarehouse subversion repository. Look in
99
+ the SVN_ROOT/demo directory.
@@ -0,0 +1,165 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+ require 'rake/gempackagetask'
5
+ require 'rake/contrib/rubyforgepublisher'
6
+ require 'spec/version'
7
+ require 'spec/rake/spectask'
8
+
9
+ require File.join(File.dirname(__FILE__), 'lib/active_warehouse', 'version')
10
+
11
+ module AW
12
+ PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
13
+ PKG_NAME = 'activewarehouse'
14
+ PKG_VERSION = ActiveWarehouse::VERSION::STRING + PKG_BUILD
15
+ PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
16
+ PKG_DESTINATION = ENV["PKG_DESTINATION"] || "../#{PKG_NAME}"
17
+ end
18
+
19
+ desc 'Default: run tests and specs.'
20
+ task :default => [:test, :spec]
21
+
22
+ desc 'Test the active_warehouse plugin.'
23
+ Rake::TestTask.new(:test) do |t|
24
+ t.libs << 'lib'
25
+ t.pattern = 'test/**/*_test.rb'
26
+ t.verbose = true
27
+ end
28
+
29
+ desc "Run all specs"
30
+ Spec::Rake::SpecTask.new do |t|
31
+ t.spec_files = FileList['spec/**/*_spec.rb']
32
+ t.spec_opts = ['--options', 'spec/spec.opts']
33
+ unless ENV['NO_RCOV']
34
+ t.rcov = true
35
+ t.rcov_dir = '../doc/output/coverage'
36
+ t.rcov_opts = ['--exclude', 'spec\/spec,bin\/spec,examples,\/var\/lib\/gems,\/Library\/Ruby,\.autotest']
37
+ end
38
+ end
39
+
40
+ namespace :rcov do
41
+ desc 'Measures test coverage'
42
+ task :test do
43
+ rm_f 'coverage.data'
44
+ mkdir 'coverage' unless File.exist?('coverage')
45
+ rcov = "rcov --aggregate coverage.data --text-summary -Ilib"
46
+ system("#{rcov} test/*_test.rb")
47
+ system("open coverage/index.html") if PLATFORM['darwin']
48
+ end
49
+ end
50
+
51
+ desc 'Generate documentation for the active_warehouse plugin.'
52
+ Rake::RDocTask.new(:rdoc) do |rdoc|
53
+ rdoc.rdoc_dir = 'rdoc'
54
+ rdoc.title = 'ActiveWarehouse'
55
+ rdoc.options << '--line-numbers' << '--inline-source'
56
+ rdoc.rdoc_files.include('README')
57
+ rdoc.rdoc_files.include('lib/**/*.rb')
58
+ end
59
+
60
+ # Gem Spec
61
+ module AW
62
+ def self.package_files(package_prefix)
63
+ FileList[
64
+ "#{package_prefix}[a-zA-Z]*.rb",
65
+ "#{package_prefix}README",
66
+ "#{package_prefix}TODO",
67
+ "#{package_prefix}Rakefile",
68
+ "#{package_prefix}db/**/*",
69
+ "#{package_prefix}doc/**/*",
70
+ "#{package_prefix}generators/**/*",
71
+ "#{package_prefix}lib/**/*",
72
+ "#{package_prefix}tasks/**/*"
73
+ ] - [ "#{package_prefix}test" ]
74
+ end
75
+
76
+ def self.spec(package_prefix = '')
77
+ Gem::Specification.new do |s|
78
+ s.name = 'activewarehouse'
79
+ s.version = AW::PKG_VERSION
80
+ s.summary = "Build data warehouses with Rails."
81
+ s.description = <<-EOF
82
+ ActiveWarehouse extends Rails to provide functionality specific for building data warehouses.
83
+ EOF
84
+
85
+ s.add_dependency('rake', '>= 0.7.1')
86
+ s.add_dependency('fastercsv', '>= 1.1.0')
87
+ s.add_dependency('activesupport', '>= 1.3.1')
88
+ s.add_dependency('activerecord', '>= 1.14.4')
89
+ s.add_dependency('actionpack', '>= 1.12.5')
90
+ s.add_dependency('rails_sql_views', '>= 0.1.0')
91
+ s.add_dependency('adapter_extensions', '>= 0.1.0')
92
+
93
+ s.rdoc_options << '--exclude' << '.'
94
+ s.has_rdoc = false
95
+
96
+ s.files = package_files(package_prefix).to_a.delete_if {|f| f.include?('.svn')}
97
+ s.require_path = 'lib'
98
+
99
+ #s.bindir = "bin" # Use these for applications.
100
+ #s.executables = []
101
+ #s.default_executable = ""
102
+
103
+ s.author = "Anthony Eden"
104
+ s.email = "anthonyeden@gmail.com"
105
+ s.homepage = "http://activewarehouse.rubyforge.org"
106
+ s.rubyforge_project = "activewarehouse"
107
+ end
108
+ end
109
+ end
110
+
111
+ Rake::GemPackageTask.new(AW.spec) do |pkg|
112
+ pkg.gem_spec = AW.spec
113
+ pkg.need_tar = true
114
+ pkg.need_zip = true
115
+ end
116
+
117
+ desc "Generate code statistics"
118
+ task :lines do
119
+ lines, codelines, total_lines, total_codelines = 0, 0, 0, 0
120
+
121
+ for file_name in FileList["lib/**/*.rb"]
122
+ next if file_name =~ /vendor/
123
+ f = File.open(file_name)
124
+
125
+ while line = f.gets
126
+ lines += 1
127
+ next if line =~ /^\s*$/
128
+ next if line =~ /^\s*#/
129
+ codelines += 1
130
+ end
131
+ puts "L: #{sprintf("%4d", lines)}, LOC #{sprintf("%4d", codelines)} | #{file_name}"
132
+
133
+ total_lines += lines
134
+ total_codelines += codelines
135
+
136
+ lines, codelines = 0, 0
137
+ end
138
+
139
+ puts "Total: Lines #{total_lines}, LOC #{total_codelines}"
140
+ end
141
+
142
+ desc "Publish the release files to RubyForge."
143
+ task :release => [ :package ] do
144
+ `rubyforge login`
145
+
146
+ for ext in %w( gem tgz zip )
147
+ release_command = "rubyforge add_release activewarehouse #{AW::PKG_NAME} 'REL #{AW::PKG_VERSION}' pkg/#{AW::PKG_NAME}-#{AW::PKG_VERSION}.#{ext}"
148
+ puts release_command
149
+ system(release_command)
150
+ end
151
+ end
152
+
153
+ desc "Publish the API documentation"
154
+ task :pdoc => [:rdoc] do
155
+ Rake::SshDirPublisher.new("aeden@rubyforge.org", "/var/www/gforge-projects/activewarehouse/rdoc", "rdoc").upload
156
+ end
157
+
158
+ desc "Reinstall the gem from a local package copy"
159
+ task :reinstall => [:package] do
160
+ windows = RUBY_PLATFORM =~ /mswin/
161
+ sudo = windows ? '' : 'sudo'
162
+ gem = windows ? 'gem.bat' : 'gem'
163
+ `#{sudo} #{gem} uninstall -x -i #{AW::PKG_NAME}`
164
+ `#{sudo} #{gem} install pkg/#{AW::PKG_NAME}-#{AW::PKG_VERSION}`
165
+ end
@@ -0,0 +1,4 @@
1
+ TODO list:
2
+
3
+ * Modify the fact generator so that the migration has a map for foreign key and a map for fact attributes. The foreign keys can then automatically be indexed as that is pretty much standard behavior.
4
+ * Make the belongs_to connection between facts and dimensions automatic.
@@ -0,0 +1,28 @@
1
+ class CreateTableReports < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :table_reports do |t|
4
+ t.column :title, :string
5
+ t.column :cube_name, :string, :null => false
6
+
7
+ t.column :column_dimension_name, :string
8
+ t.column :column_hierarchy, :string
9
+ t.column :column_constraints, :text
10
+ t.column :column_stage, :integer
11
+ t.column :column_param_prefix, :string
12
+
13
+ t.column :row_dimension_name, :string
14
+ t.column :row_hierarchy, :string
15
+ t.column :row_constraints, :text
16
+ t.column :row_stage, :integer
17
+ t.column :row_param_prefix, :string
18
+
19
+ t.column :fact_attributes, :text
20
+
21
+ t.column :created_at, :datetime
22
+ t.column :updated_at, :datetime
23
+ end
24
+ end
25
+ def self.down
26
+ drop_table :table_reports
27
+ end
28
+ end
@@ -0,0 +1,4 @@
1
+ The following papers are relevant to building, storing and querying data cubes with large databases.
2
+
3
+ http://research.microsoft.com/research/pubs/view.aspx?msr_tr_id=MSR-TR-95-22
4
+ http://dbpubs.stanford.edu/pub/showDoc.Fulltext?lang=en&doc=1995-34&format=pdf&compression=&name=1995-34.pdf
@@ -0,0 +1 @@
1
+ ./script/generate bridge NAME
@@ -0,0 +1,46 @@
1
+ class BridgeGenerator < Rails::Generator::NamedBase
2
+ attr_accessor :file_name
3
+
4
+ default_options :skip_migration => false
5
+
6
+ def initialize(runtime_args, runtime_options = {})
7
+ super
8
+
9
+ @name = @name.tableize.singularize
10
+ @table_name = "#{@name}_bridge"
11
+ @class_name = "#{@name.camelize}Bridge"
12
+ @file_name = "#{@class_name.tableize.singularize}"
13
+ end
14
+
15
+ def manifest
16
+ record do |m|
17
+ # Check for class naming collisions.
18
+ m.class_collisions class_path, "#{class_name}", "#{class_name}Test"
19
+
20
+ # Create required directories if necessary
21
+ m.directory File.join('app/models', class_path)
22
+ m.directory File.join('test/unit', class_path)
23
+ m.directory File.join('test/fixtures', class_path)
24
+
25
+ # Generate the files
26
+ m.template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
27
+ m.template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb")
28
+ m.template 'fixture.yml', File.join('test/fixtures', class_path, "#{table_name}.yml")
29
+
30
+ # Generate the migration unless :skip_migration option is specified
31
+ unless options[:skip_migration]
32
+ m.migration_template 'migration.rb', 'db/migrate', :assigns => {
33
+ :migration_name => "Create#{class_name.gsub(/::/, '')}"
34
+ }, :migration_file_name => "create_#{file_name.gsub(/\//, '_')}"
35
+ end
36
+ end
37
+ end
38
+
39
+ protected
40
+ def add_options!(opt)
41
+ opt.separator ''
42
+ opt.separator 'Options:'
43
+ opt.on("--skip-migration",
44
+ "Don't generate a migration file for this bridge") { |v| options[:skip_migration] = v }
45
+ end
46
+ end
@@ -0,0 +1,5 @@
1
+ # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2
+ first:
3
+ id: 1
4
+ another:
5
+ id: 2
@@ -0,0 +1,27 @@
1
+ class <%= migration_name %> < ActiveRecord::Migration
2
+ def self.up
3
+ fields = {
4
+ # the following are the required bridge table columns for
5
+ # variable depth hierarchies. Do not change them unless you know
6
+ # what you are doing.
7
+ :parent_id => :integer,
8
+ :child_id => :integer,
9
+ :num_levels_from_parent => :integer,
10
+ :is_bottom => :boolean,
11
+ :is_top => :boolean
12
+ }
13
+ create_table :<%= table_name %> do |t|
14
+ fields.each do |name,type|
15
+ t.column name, type
16
+ end
17
+ end
18
+ fields.each do |name,type|
19
+ add_index :<%= table_name %>, name unless type == :text
20
+ end
21
+ add_index :<%= table_name %>, [:parent_id, :child_id, :num_levels_from_parent], :unique => true
22
+ end
23
+
24
+ def self.down
25
+ drop_table :<%= table_name %>
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ class <%= class_name %> < ActiveWarehouse::Bridge
2
+
3
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../test_helper'
2
+
3
+ class <%= class_name %>Test < Test::Unit::TestCase
4
+ # Replace this with your real tests.
5
+ def test_truth
6
+ assert true
7
+ end
8
+ end
@@ -0,0 +1 @@
1
+ ./script/generate cube NAME
@@ -0,0 +1,28 @@
1
+ class CubeGenerator < Rails::Generator::NamedBase
2
+ attr_accessor :file_name
3
+
4
+ def initialize(runtime_args, runtime_options = {})
5
+ super
6
+
7
+ @name = @name.underscore
8
+ @table_name = "#{@name}_cube"
9
+ @class_name = "#{@name.camelize}Cube"
10
+ @file_name = "#{@class_name.tableize.singularize}"
11
+ end
12
+
13
+ def manifest
14
+ record do |m|
15
+ # Check for class naming collisions.
16
+ m.class_collisions class_path, "#{class_name}", "#{class_name}Test"
17
+
18
+ # Create required directories if necessary
19
+ m.directory File.join('app/models', class_path)
20
+ m.directory File.join('test/unit', class_path)
21
+
22
+ # Generate the files
23
+ m.template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
24
+ m.template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb")
25
+ end
26
+ end
27
+
28
+ end
@@ -0,0 +1,3 @@
1
+ class <%= class_name %> < ActiveWarehouse::Cube
2
+
3
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../test_helper'
2
+
3
+ class <%= class_name %>Test < Test::Unit::TestCase
4
+ # Replace this with your real tests.
5
+ def test_truth
6
+ assert true
7
+ end
8
+ end