mainej-activewarehouse 0.3.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.
- data/activewarehouse/README +99 -0
- data/activewarehouse/Rakefile +165 -0
- data/activewarehouse/TODO +4 -0
- data/activewarehouse/db/migrations/001_create_table_reports.rb +28 -0
- data/activewarehouse/doc/references.txt +4 -0
- data/activewarehouse/generators/bridge/USAGE +1 -0
- data/activewarehouse/generators/bridge/bridge_generator.rb +46 -0
- data/activewarehouse/generators/bridge/templates/fixture.yml +5 -0
- data/activewarehouse/generators/bridge/templates/migration.rb +27 -0
- data/activewarehouse/generators/bridge/templates/model.rb +3 -0
- data/activewarehouse/generators/bridge/templates/unit_test.rb +8 -0
- data/activewarehouse/generators/cube/USAGE +1 -0
- data/activewarehouse/generators/cube/cube_generator.rb +28 -0
- data/activewarehouse/generators/cube/templates/model.rb +3 -0
- data/activewarehouse/generators/cube/templates/unit_test.rb +8 -0
- data/activewarehouse/generators/date_dimension/USAGE +1 -0
- data/activewarehouse/generators/date_dimension/date_dimension_generator.rb +16 -0
- data/activewarehouse/generators/date_dimension/templates/fixture.yml +5 -0
- data/activewarehouse/generators/date_dimension/templates/migration.rb +31 -0
- data/activewarehouse/generators/date_dimension/templates/model.rb +3 -0
- data/activewarehouse/generators/date_dimension/templates/unit_test.rb +8 -0
- data/activewarehouse/generators/dimension/USAGE +1 -0
- data/activewarehouse/generators/dimension/dimension_generator.rb +46 -0
- data/activewarehouse/generators/dimension/templates/fixture.yml +5 -0
- data/activewarehouse/generators/dimension/templates/migration.rb +11 -0
- data/activewarehouse/generators/dimension/templates/model.rb +3 -0
- data/activewarehouse/generators/dimension/templates/unit_test.rb +8 -0
- data/activewarehouse/generators/dimension_view/USAGE +1 -0
- data/activewarehouse/generators/dimension_view/dimension_view_generator.rb +62 -0
- data/activewarehouse/generators/dimension_view/templates/migration.rb +17 -0
- data/activewarehouse/generators/dimension_view/templates/model.rb +3 -0
- data/activewarehouse/generators/dimension_view/templates/unit_test.rb +10 -0
- data/activewarehouse/generators/fact/USAGE +1 -0
- data/activewarehouse/generators/fact/fact_generator.rb +46 -0
- data/activewarehouse/generators/fact/templates/fixture.yml +5 -0
- data/activewarehouse/generators/fact/templates/migration.rb +13 -0
- data/activewarehouse/generators/fact/templates/model.rb +3 -0
- data/activewarehouse/generators/fact/templates/unit_test.rb +10 -0
- data/activewarehouse/generators/time_dimension/USAGE +1 -0
- data/activewarehouse/generators/time_dimension/templates/fixture.yml +5 -0
- data/activewarehouse/generators/time_dimension/templates/migration.rb +12 -0
- data/activewarehouse/generators/time_dimension/templates/model.rb +3 -0
- data/activewarehouse/generators/time_dimension/templates/unit_test.rb +8 -0
- data/activewarehouse/generators/time_dimension/time_dimension_generator.rb +14 -0
- data/activewarehouse/init.rb +1 -0
- data/activewarehouse/install.rb +5 -0
- data/activewarehouse/lib/active_warehouse.rb +91 -0
- data/activewarehouse/lib/active_warehouse/aggregate.rb +75 -0
- data/activewarehouse/lib/active_warehouse/aggregate/dwarf_aggregate.rb +369 -0
- data/activewarehouse/lib/active_warehouse/aggregate/dwarf_common.rb +44 -0
- data/activewarehouse/lib/active_warehouse/aggregate/dwarf_printer.rb +34 -0
- data/activewarehouse/lib/active_warehouse/aggregate/no_aggregate.rb +212 -0
- data/activewarehouse/lib/active_warehouse/aggregate/pid_aggregate.rb +29 -0
- data/activewarehouse/lib/active_warehouse/aggregate_field.rb +59 -0
- data/activewarehouse/lib/active_warehouse/bridge.rb +19 -0
- data/activewarehouse/lib/active_warehouse/bridge/hierarchy_bridge.rb +46 -0
- data/activewarehouse/lib/active_warehouse/builder.rb +3 -0
- data/activewarehouse/lib/active_warehouse/builder/date_dimension_builder.rb +91 -0
- data/activewarehouse/lib/active_warehouse/builder/generator/generator.rb +13 -0
- data/activewarehouse/lib/active_warehouse/builder/generator/name_generator.rb +20 -0
- data/activewarehouse/lib/active_warehouse/builder/generator/paragraph_generator.rb +11 -0
- data/activewarehouse/lib/active_warehouse/builder/random_data_builder.rb +239 -0
- data/activewarehouse/lib/active_warehouse/builder/test_data_builder.rb +54 -0
- data/activewarehouse/lib/active_warehouse/calculated_field.rb +27 -0
- data/activewarehouse/lib/active_warehouse/compat/compat.rb +49 -0
- data/activewarehouse/lib/active_warehouse/core_ext.rb +1 -0
- data/activewarehouse/lib/active_warehouse/core_ext/time.rb +5 -0
- data/activewarehouse/lib/active_warehouse/core_ext/time/calculations.rb +40 -0
- data/activewarehouse/lib/active_warehouse/cube.rb +235 -0
- data/activewarehouse/lib/active_warehouse/cube_query_result.rb +69 -0
- data/activewarehouse/lib/active_warehouse/dimension.rb +329 -0
- data/activewarehouse/lib/active_warehouse/dimension/date_dimension.rb +15 -0
- data/activewarehouse/lib/active_warehouse/dimension/dimension_reflection.rb +21 -0
- data/activewarehouse/lib/active_warehouse/dimension/dimension_view.rb +27 -0
- data/activewarehouse/lib/active_warehouse/dimension/hierarchical_dimension.rb +99 -0
- data/activewarehouse/lib/active_warehouse/dimension/slowly_changing_dimension.rb +147 -0
- data/activewarehouse/lib/active_warehouse/fact.rb +239 -0
- data/activewarehouse/lib/active_warehouse/field.rb +74 -0
- data/activewarehouse/lib/active_warehouse/migrations.rb +64 -0
- data/activewarehouse/lib/active_warehouse/ordered_hash.rb +34 -0
- data/activewarehouse/lib/active_warehouse/prejoin_fact.rb +97 -0
- data/activewarehouse/lib/active_warehouse/report.rb +7 -0
- data/activewarehouse/lib/active_warehouse/report/abstract_report.rb +149 -0
- data/activewarehouse/lib/active_warehouse/report/chart_report.rb +9 -0
- data/activewarehouse/lib/active_warehouse/report/data_cell.rb +21 -0
- data/activewarehouse/lib/active_warehouse/report/data_column.rb +19 -0
- data/activewarehouse/lib/active_warehouse/report/data_row.rb +15 -0
- data/activewarehouse/lib/active_warehouse/report/dimension.rb +58 -0
- data/activewarehouse/lib/active_warehouse/report/table_report.rb +38 -0
- data/activewarehouse/lib/active_warehouse/version.rb +9 -0
- data/activewarehouse/lib/active_warehouse/view.rb +9 -0
- data/activewarehouse/lib/active_warehouse/view/crumb.rb +64 -0
- data/activewarehouse/lib/active_warehouse/view/report_helper.rb +98 -0
- data/activewarehouse/lib/active_warehouse/view/table_view.rb +134 -0
- data/activewarehouse/lib/active_warehouse/view/yui_adapter.rb +68 -0
- data/activewarehouse/tasks/active_warehouse_tasks.rake +122 -0
- 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,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 @@
|
|
|
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
|