rubiks 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +30 -15
- data/.rvmrc +1 -0
- data/.travis.yml +3 -4
- data/.yardopts +6 -0
- data/CHANGELOG.md +21 -0
- data/CONTRIBUTIG.md +46 -0
- data/Gemfile +4 -1
- data/{LICENSE.txt → LICENSE.md} +1 -2
- data/README.md +97 -4
- data/Rakefile +8 -1
- data/examples/mondrian_docs.yml +36 -0
- data/lib/rubiks/examples.rb +61 -0
- data/lib/rubiks/nodes/annotated_node.rb +6 -0
- data/lib/rubiks/nodes/calculated_member.rb +81 -0
- data/lib/rubiks/nodes/cube.rb +74 -2
- data/lib/rubiks/nodes/dimension.rb +18 -0
- data/lib/rubiks/nodes/hierarchy.rb +47 -2
- data/lib/rubiks/nodes/level.rb +106 -2
- data/lib/rubiks/nodes/measure.rb +23 -14
- data/lib/rubiks/nodes/schema.rb +19 -8
- data/lib/rubiks/nodes/validated_node.rb +33 -1
- data/lib/rubiks/version.rb +1 -1
- data/rubiks.gemspec +4 -2
- data/spec/examples/mondrian_docs_example_spec.rb +108 -0
- data/spec/examples/simple_mondrian_example_spec.rb +84 -0
- data/spec/rubiks/nodes/calculated_member_spec.rb +50 -0
- data/spec/rubiks/nodes/cube_spec.rb +32 -8
- data/spec/rubiks/nodes/dimension_spec.rb +15 -0
- data/spec/rubiks/nodes/hierarchy_spec.rb +22 -1
- data/spec/rubiks/nodes/level_spec.rb +68 -1
- data/spec/rubiks/nodes/measure_spec.rb +29 -5
- data/spec/rubiks/nodes/schema_spec.rb +2 -23
- data/spec/spec_helper.rb +30 -11
- data/spec/support/schema_context.rb +17 -4
- metadata +26 -10
- data/Guardfile +0 -5
- data/spec/examples/mondrian_xml_example_spec.rb +0 -91
data/.gitignore
CHANGED
@@ -1,20 +1,35 @@
|
|
1
|
-
|
2
|
-
*.
|
1
|
+
## TEXTMATE
|
2
|
+
*.tmproj
|
3
|
+
tmtags
|
4
|
+
|
5
|
+
## EMACS
|
6
|
+
*~
|
7
|
+
\#*
|
8
|
+
.\#*
|
9
|
+
|
10
|
+
## VIM
|
3
11
|
*.swp
|
4
|
-
|
5
|
-
|
6
|
-
.config
|
7
|
-
.vagrant
|
12
|
+
|
13
|
+
## PROJECT::GENERAL
|
8
14
|
.yardoc
|
9
|
-
Gemfile.lock
|
10
|
-
InstalledFiles
|
11
|
-
_yardoc
|
12
15
|
coverage
|
13
|
-
doc
|
14
|
-
|
16
|
+
doc
|
17
|
+
log
|
15
18
|
pkg
|
16
19
|
rdoc
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
20
|
+
|
21
|
+
## BUNDLER
|
22
|
+
*.gem
|
23
|
+
.bundle
|
24
|
+
pkg
|
25
|
+
Gemfile.lock
|
26
|
+
|
27
|
+
## RBENV
|
28
|
+
.ruby-version
|
29
|
+
.rbenv*
|
30
|
+
|
31
|
+
## RCOV
|
32
|
+
coverage.data
|
33
|
+
|
34
|
+
## RUBINIUS
|
35
|
+
*.rbc
|
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use 1.9.3
|
data/.travis.yml
CHANGED
data/.yardopts
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
0.0.5
|
2
|
+
-----
|
3
|
+
* [0.0.5 release](https://github.com/moneydesktop/rubiks/pull/2)
|
4
|
+
|
5
|
+
0.0.4
|
6
|
+
-----
|
7
|
+
* [Bump to v0.0.4](https://github.com/moneydesktop/rubiks/commit/38dfd1f82e947f39457670adfdc6ca67da2728c6)
|
8
|
+
* [Add GemVersion badge to README](https://github.com/moneydesktop/rubiks/commit/2d92097c4ba73d92690fab78455fc7db6ed0b3d9)
|
9
|
+
|
10
|
+
0.0.3
|
11
|
+
-----
|
12
|
+
* [Bump to v0.0.3](https://github.com/moneydesktop/rubiks/commit/23ceb29936f663605527a12ca2d2a5c623abe99e)
|
13
|
+
* Need to fill in other commits here
|
14
|
+
|
15
|
+
0.0.2
|
16
|
+
-----
|
17
|
+
* [Bump to v0.0.2](https://github.com/moneydesktop/rubiks/commit/14a55449be9552268c66cbf8b902af02cf7b73c6)
|
18
|
+
|
19
|
+
0.0.1
|
20
|
+
-----
|
21
|
+
* [Initial RubyGem project](https://github.com/moneydesktop/rubiks/commit/fa8be4badf70e86fda7e14bf23f9230a926893d2)
|
data/CONTRIBUTIG.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
## Contributing
|
2
|
+
In the spirit of [free software][free-sw], **everyone** is encouraged to help
|
3
|
+
improve this project.
|
4
|
+
|
5
|
+
[free-sw]: http://www.fsf.org/licensing/essays/free-sw.html
|
6
|
+
|
7
|
+
Here are some ways *you* can contribute:
|
8
|
+
|
9
|
+
* by using alpha, beta, and prerelease versions
|
10
|
+
* by reporting bugs
|
11
|
+
* by suggesting new features
|
12
|
+
* by writing or editing documentation
|
13
|
+
* by writing specifications
|
14
|
+
* by writing code ( **no patch is too small**: fix typos, add comments, clean up
|
15
|
+
inconsistent whitespace)
|
16
|
+
* by refactoring code
|
17
|
+
* by closing [issues][]
|
18
|
+
* by reviewing patches
|
19
|
+
|
20
|
+
[issues]: https://github.com/moneydesktop/rubiks/issues
|
21
|
+
|
22
|
+
## Submitting an Issue
|
23
|
+
We use the [GitHub issue tracker][issues] to track bugs and features. Before
|
24
|
+
submitting a bug report or feature request, check to make sure it hasn't
|
25
|
+
already been submitted. When submitting a bug report, please include a [Gist][]
|
26
|
+
that includes a stack trace and any details that may be necessary to reproduce
|
27
|
+
the bug, including your gem version, Ruby version, and operating system.
|
28
|
+
Ideally, a bug report should include a pull request with failing specs.
|
29
|
+
|
30
|
+
[gist]: https://gist.github.com/
|
31
|
+
|
32
|
+
## Submitting a Pull Request
|
33
|
+
1. [Fork the repository.][fork]
|
34
|
+
2. [Create a topic branch.][branch]
|
35
|
+
3. Add specs for your unimplemented feature or bug fix.
|
36
|
+
4. Run `bundle exec rake spec`. If your specs pass, return to step 3.
|
37
|
+
5. Implement your feature or bug fix.
|
38
|
+
6. Run `bundle exec rake spec`. If your specs fail, return to step 5.
|
39
|
+
7. Run `open coverage/index.html`. If your changes are not completely covered
|
40
|
+
by your tests, return to step 3.
|
41
|
+
8. Add, commit, and push your changes.
|
42
|
+
9. [Submit a pull request.][pr]
|
43
|
+
|
44
|
+
[fork]: http://help.github.com/fork-a-repo/
|
45
|
+
[branch]: http://learn.github.com/p/branching.html
|
46
|
+
[pr]: http://help.github.com/send-pull-requests/
|
data/Gemfile
CHANGED
@@ -7,13 +7,16 @@ gemspec
|
|
7
7
|
# so CI can include just test dependencies
|
8
8
|
group :test do
|
9
9
|
gem 'rake'
|
10
|
+
gem 'yard'
|
11
|
+
gem 'coveralls', :require => false
|
12
|
+
gem 'simplecov', :require => false
|
10
13
|
gem 'rspec'
|
11
14
|
gem 'rspec-pride'
|
12
15
|
end
|
13
16
|
|
14
17
|
group :development do
|
15
18
|
gem 'awesome_print'
|
19
|
+
gem 'kramdown'
|
16
20
|
gem 'pry'
|
17
21
|
gem 'pry-nav'
|
18
|
-
gem 'simplecov'
|
19
22
|
end
|
data/{LICENSE.txt → LICENSE.md}
RENAMED
data/README.md
CHANGED
@@ -1,10 +1,18 @@
|
|
1
1
|
# Rubiks
|
2
2
|
|
3
|
-
[![Gem Version](https://badge.fury.io/rb/rubiks.png)]
|
4
|
-
[![Build Status](https://secure.travis-ci.org/moneydesktop/rubiks.png?branch=master)]
|
5
|
-
[![
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/rubiks.png)][gem]
|
4
|
+
[![Build Status](https://secure.travis-ci.org/moneydesktop/rubiks.png?branch=master)][travis]
|
5
|
+
[![Dependency Status](https://gemnasium.com/moneydesktop/rubiks.png?travis)][gemnasium]
|
6
|
+
[![Code Climate](https://codeclimate.com/github/moneydesktop/rubiks.png)][codeclimate]
|
7
|
+
[![Coverage Status](https://coveralls.io/repos/moneydesktop/rubiks/badge.png?branch=master)][coveralls]
|
6
8
|
|
7
|
-
|
9
|
+
[gem]: https://rubygems.org/gems/rubiks
|
10
|
+
[travis]: http://travis-ci.org/moneydesktop/rubiks
|
11
|
+
[gemnasium]: https://gemnasium.com/moneydesktop/rubiks
|
12
|
+
[codeclimate]: https://codeclimate.com/github/moneydesktop/rubiks
|
13
|
+
[coveralls]: https://coveralls.io/r/moneydesktop/rubiks
|
14
|
+
|
15
|
+
A gem to allow defining an OLAP schema from a hash and generating an XML schema for Mondrian.
|
8
16
|
|
9
17
|
## Installation
|
10
18
|
|
@@ -14,6 +22,91 @@ Or you can add the following to your Gemfile and run the `bundle` command to ins
|
|
14
22
|
|
15
23
|
gem 'rubiks'
|
16
24
|
|
25
|
+
## Examples
|
26
|
+
|
27
|
+
This is an example taken from the [Mondrian documentation](http://mondrian.pentaho.com/documentation/schema.php#Cubes_and_dimensions) (then simplified a little and modified to use some Rails/Rubiks conventions)
|
28
|
+
|
29
|
+
After installing the gem, fire up an IRB session with `irb` or `bundle exec irb` if you are using Bundler, and follow this (or even paste it into your session):
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
require 'rubiks/examples'
|
33
|
+
|
34
|
+
md = Rubiks::Examples::MondrianDocs.new
|
35
|
+
|
36
|
+
md.filename # => "/path/to/rubiks/examples/mondrian_docs.yml"
|
37
|
+
|
38
|
+
puts md.file_contents # see the YAML section below
|
39
|
+
|
40
|
+
puts md.to_xml # see the XML section below
|
41
|
+
```
|
42
|
+
|
43
|
+
The [example YAML file](examples/mondrian_docs.yml) contents are:
|
44
|
+
|
45
|
+
```yaml
|
46
|
+
cubes:
|
47
|
+
- name: sales
|
48
|
+
dimensions:
|
49
|
+
- name: date
|
50
|
+
hierarchies:
|
51
|
+
- name: year_quarter_month
|
52
|
+
levels:
|
53
|
+
- name: year
|
54
|
+
column: the_year
|
55
|
+
data_type: numeric
|
56
|
+
|
57
|
+
- name: quarter
|
58
|
+
data_type: string
|
59
|
+
|
60
|
+
- name: month
|
61
|
+
column: month_of_year
|
62
|
+
data_type: Numeric
|
63
|
+
|
64
|
+
measures:
|
65
|
+
- name: unit_sales
|
66
|
+
aggregator: sum
|
67
|
+
format_string: '#,###'
|
68
|
+
|
69
|
+
- name: store_sales
|
70
|
+
aggregator: sum
|
71
|
+
format_string: '#,###'
|
72
|
+
|
73
|
+
- name: store_cost
|
74
|
+
aggregator: sum
|
75
|
+
format_string: '#,###'
|
76
|
+
|
77
|
+
calculated_members:
|
78
|
+
- name: profit
|
79
|
+
dimension: measures
|
80
|
+
formula: '[Measures].[Store Sales] / [Measures].[Store Cost]'
|
81
|
+
format_string: '$#,##0.00'
|
82
|
+
```
|
83
|
+
|
84
|
+
and the generated XML is:
|
85
|
+
|
86
|
+
|
87
|
+
```xml
|
88
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
89
|
+
<schema name="default">
|
90
|
+
<cube name="Sales">
|
91
|
+
<table name="view_sales"/>
|
92
|
+
<dimension name="Date" foreignKey="date_id">
|
93
|
+
<hierarchy name="Year Quarter Month" primaryKey="id" hasAll="true">
|
94
|
+
<table name="view_dates"/>
|
95
|
+
<level name="Year" column="the_year" type="Numeric"/>
|
96
|
+
<level name="Quarter" column="quarter" type="String"/>
|
97
|
+
<level name="Month" column="month_of_year" type="Numeric"/>
|
98
|
+
</hierarchy>
|
99
|
+
</dimension>
|
100
|
+
<measure name="Unit Sales" aggregator="sum" formatString="#,###" column="unit_sales"/>
|
101
|
+
<measure name="Store Sales" aggregator="sum" formatString="#,###" column="store_sales"/>
|
102
|
+
<measure name="Store Cost" aggregator="sum" formatString="#,###" column="store_cost"/>
|
103
|
+
<calculatedMember name="Profit" dimension="Measures" formula="[Measures].[Store Sales] / [Measures].[Store Cost]">
|
104
|
+
<calculatedMemberProperty name="FORMAT_STRING" value="$#,##0.00"/>
|
105
|
+
</calculatedMember>
|
106
|
+
</cube>
|
107
|
+
</schema>
|
108
|
+
```
|
109
|
+
|
17
110
|
## Contributing
|
18
111
|
|
19
112
|
1. Fork it
|
data/Rakefile
CHANGED
@@ -1,5 +1,12 @@
|
|
1
|
-
require '
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
2
3
|
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
desc 'Run all specs'
|
3
6
|
RSpec::Core::RakeTask.new(:spec)
|
4
7
|
|
5
8
|
task :default => :spec
|
9
|
+
task :test => :spec
|
10
|
+
|
11
|
+
require 'yard'
|
12
|
+
YARD::Rake::YardocTask.new
|
@@ -0,0 +1,36 @@
|
|
1
|
+
cubes:
|
2
|
+
- name: sales
|
3
|
+
dimensions:
|
4
|
+
- name: date
|
5
|
+
hierarchies:
|
6
|
+
- name: year_quarter_month
|
7
|
+
levels:
|
8
|
+
- name: year
|
9
|
+
column: the_year
|
10
|
+
data_type: numeric
|
11
|
+
|
12
|
+
- name: quarter
|
13
|
+
data_type: string
|
14
|
+
|
15
|
+
- name: month
|
16
|
+
column: month_of_year
|
17
|
+
data_type: Numeric
|
18
|
+
|
19
|
+
measures:
|
20
|
+
- name: unit_sales
|
21
|
+
aggregator: sum
|
22
|
+
format_string: '#,###'
|
23
|
+
|
24
|
+
- name: store_sales
|
25
|
+
aggregator: sum
|
26
|
+
format_string: '#,###'
|
27
|
+
|
28
|
+
- name: store_cost
|
29
|
+
aggregator: sum
|
30
|
+
format_string: '#,###'
|
31
|
+
|
32
|
+
calculated_members:
|
33
|
+
- name: profit
|
34
|
+
dimension: measures
|
35
|
+
formula: '[Measures].[Store Sales] / [Measures].[Store Cost]'
|
36
|
+
format_string: '$#,##0.00'
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'rubiks'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module ::Rubiks
|
5
|
+
module Examples
|
6
|
+
|
7
|
+
# This example is taken from the Mondrian documentation:
|
8
|
+
# http://mondrian.pentaho.com/documentation/schema.php#Cubes_and_dimensions
|
9
|
+
# then modified to use Rails/Rubiks conventions
|
10
|
+
#
|
11
|
+
# We want the output to be:
|
12
|
+
#
|
13
|
+
# <?xml version="1.0" encoding="UTF-8"?>
|
14
|
+
# <schema name="default">
|
15
|
+
# <cube name="Sales">
|
16
|
+
# <table name="view_sales"/>
|
17
|
+
#
|
18
|
+
# <dimension name="Date" foreignKey="date_id">
|
19
|
+
# <hierarchy name="Year Quarter Month" primaryKey="id" hasAll="true">
|
20
|
+
# <table name="view_dates"/>
|
21
|
+
# <level name="Year" column="the_year" type="Numeric"/>
|
22
|
+
# <level name="Quarter" column="quarter" type="String"/>
|
23
|
+
# <level name="Month" column="month_of_year" type="Numeric"/>
|
24
|
+
# </hierarchy>
|
25
|
+
# </dimension>
|
26
|
+
#
|
27
|
+
# <measure name="Unit Sales" aggregator="sum" formatString="#,###" column="unit_sales"/>
|
28
|
+
# <measure name="Store Sales" aggregator="sum" formatString="#,###" column="store_sales"/>
|
29
|
+
# <measure name="Store Cost" aggregator="sum" formatString="#,###" column="store_cost"/>
|
30
|
+
#
|
31
|
+
# <calculatedMember name="Profit" dimension="Measures" formula="[Measures].[Store Sales] / [Measures].[Store Cost]">
|
32
|
+
# <calculatedMemberProperty name="FORMAT_STRING" value="$#,##0.00"/>
|
33
|
+
# </calculatedMember>
|
34
|
+
# </cube>
|
35
|
+
# </schema>
|
36
|
+
class MondrianDocs
|
37
|
+
class << self
|
38
|
+
def filename
|
39
|
+
File.expand_path('../../../examples/mondrian_docs.yml', __FILE__)
|
40
|
+
end
|
41
|
+
|
42
|
+
def file_contents
|
43
|
+
File.read(self.filename)
|
44
|
+
end
|
45
|
+
|
46
|
+
def hash
|
47
|
+
YAML.load_file(self.filename)
|
48
|
+
end
|
49
|
+
|
50
|
+
def schema
|
51
|
+
::Rubiks::Schema.new_from_hash(self.hash)
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_xml
|
55
|
+
self.schema.to_xml
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'rubiks/nodes/validated_node'
|
2
|
+
|
3
|
+
module ::Rubiks
|
4
|
+
|
5
|
+
class CalculatedMember < ::Rubiks::AnnotatedNode
|
6
|
+
value :dimension, String
|
7
|
+
value :formula, String
|
8
|
+
value :format_string, String
|
9
|
+
|
10
|
+
validates :dimension_present, :formula_present
|
11
|
+
|
12
|
+
def self.new_from_hash(hash={})
|
13
|
+
new_instance = new
|
14
|
+
return new_instance.from_hash(hash)
|
15
|
+
end
|
16
|
+
|
17
|
+
def from_hash(working_hash)
|
18
|
+
return self if working_hash.nil?
|
19
|
+
working_hash.stringify_keys!
|
20
|
+
|
21
|
+
parse_name(working_hash.delete('name'))
|
22
|
+
parse_dimension(working_hash.delete('dimension'))
|
23
|
+
parse_formula(working_hash.delete('formula'))
|
24
|
+
parse_format_string(working_hash.delete('format_string'))
|
25
|
+
return self
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_hash
|
29
|
+
hash = {}
|
30
|
+
|
31
|
+
hash['name'] = self.name.to_s if self.name.present?
|
32
|
+
hash['dimension'] = self.dimension.to_s if self.dimension.present?
|
33
|
+
hash['formula'] = self.formula.to_s if self.formula.present?
|
34
|
+
hash['format_string'] = self.format_string.to_s if self.format_string.present?
|
35
|
+
|
36
|
+
return hash
|
37
|
+
end
|
38
|
+
|
39
|
+
def dimension_present
|
40
|
+
errors << 'Dimension required on CalculatedMember' if self.dimension.blank?
|
41
|
+
end
|
42
|
+
|
43
|
+
def parse_dimension(dimension_value)
|
44
|
+
return if dimension_value.nil?
|
45
|
+
|
46
|
+
self.dimension = dimension_value.to_s
|
47
|
+
end
|
48
|
+
|
49
|
+
def formula_present
|
50
|
+
errors << 'Formula required on CalculatedMember' if self.formula.blank?
|
51
|
+
end
|
52
|
+
|
53
|
+
def parse_formula(formula_value)
|
54
|
+
return if formula_value.nil?
|
55
|
+
|
56
|
+
self.formula = formula_value.to_s
|
57
|
+
end
|
58
|
+
|
59
|
+
def parse_format_string(format_string_value)
|
60
|
+
return if format_string_value.nil?
|
61
|
+
|
62
|
+
self.format_string = format_string_value.to_s
|
63
|
+
end
|
64
|
+
|
65
|
+
def to_xml(builder = nil)
|
66
|
+
builder = Builder::XmlMarkup.new(:indent => 2) if builder.nil?
|
67
|
+
|
68
|
+
attrs = self.to_hash
|
69
|
+
attrs['name'] = self.name.titleize if self.name.present?
|
70
|
+
attrs['dimension'] = self.dimension.titleize if self.dimension.present?
|
71
|
+
attrs.delete('format_string')
|
72
|
+
builder.calculatedMember(attrs) do
|
73
|
+
if self.format_string.present?
|
74
|
+
format_attrs = {'name' => 'FORMAT_STRING', 'value' => self.format_string}
|
75
|
+
builder.calculatedMemberProperty(format_attrs)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
data/lib/rubiks/nodes/cube.rb
CHANGED
@@ -1,17 +1,24 @@
|
|
1
1
|
require 'rubiks/nodes/annotated_node'
|
2
2
|
require 'rubiks/nodes/dimension'
|
3
3
|
require 'rubiks/nodes/measure'
|
4
|
+
require 'rubiks/nodes/calculated_member'
|
4
5
|
|
5
6
|
module ::Rubiks
|
6
7
|
|
7
8
|
class Cube < ::Rubiks::AnnotatedNode
|
9
|
+
value :date_dimension, String
|
10
|
+
value :person_dimension, String
|
11
|
+
value :count_measure, String
|
12
|
+
value :person_count_measure, String
|
13
|
+
|
8
14
|
child :dimensions, [::Rubiks::Dimension]
|
9
15
|
child :measures, [::Rubiks::Measure]
|
16
|
+
child :calculated_members, [::Rubiks::CalculatedMember]
|
10
17
|
|
11
|
-
validates :dimensions_present, :measures_present
|
18
|
+
validates :dimensions_present, :measures_present, :calculated_members_if_present
|
12
19
|
|
13
20
|
def self.new_from_hash(hash={})
|
14
|
-
new_instance = new('',[],[])
|
21
|
+
new_instance = new('','','','','',[],[],[])
|
15
22
|
return new_instance.from_hash(hash)
|
16
23
|
end
|
17
24
|
|
@@ -20,11 +27,57 @@ module ::Rubiks
|
|
20
27
|
working_hash.stringify_keys!
|
21
28
|
|
22
29
|
parse_name(working_hash.delete('name'))
|
30
|
+
parse_date_dimension(working_hash.delete('date_dimension'))
|
31
|
+
parse_person_dimension(working_hash.delete('person_dimension'))
|
32
|
+
parse_count_measure(working_hash.delete('count_measure'))
|
33
|
+
parse_person_count_measure(working_hash.delete('person_count_measure'))
|
23
34
|
parse_dimensions(working_hash.delete('dimensions'))
|
24
35
|
parse_measures(working_hash.delete('measures'))
|
36
|
+
parse_calculated_members(working_hash.delete('calculated_members'))
|
25
37
|
return self
|
26
38
|
end
|
27
39
|
|
40
|
+
def parse_date_dimension(input_value)
|
41
|
+
return if input_value.nil?
|
42
|
+
|
43
|
+
self.date_dimension = input_value.to_s.underscore
|
44
|
+
end
|
45
|
+
|
46
|
+
def parse_person_dimension(input_value)
|
47
|
+
return if input_value.nil?
|
48
|
+
|
49
|
+
self.person_dimension = input_value.to_s.underscore
|
50
|
+
end
|
51
|
+
|
52
|
+
def parse_count_measure(input_value)
|
53
|
+
return if input_value.nil?
|
54
|
+
|
55
|
+
self.count_measure = input_value.to_s.underscore
|
56
|
+
end
|
57
|
+
|
58
|
+
def parse_person_count_measure(input_value)
|
59
|
+
return if input_value.nil?
|
60
|
+
|
61
|
+
self.person_count_measure = input_value.to_s.underscore
|
62
|
+
end
|
63
|
+
|
64
|
+
def calculated_members_if_present
|
65
|
+
if self.calculated_members.present?
|
66
|
+
self.calculated_members.each do |calculated_member|
|
67
|
+
calculated_member.validate
|
68
|
+
errors.push(*calculated_member.errors)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def parse_calculated_members(calculated_members_array)
|
74
|
+
return if calculated_members_array.nil? || calculated_members_array.empty?
|
75
|
+
|
76
|
+
calculated_members_array.each do |calculated_member_hash|
|
77
|
+
self.calculated_members << ::Rubiks::CalculatedMember.new_from_hash(calculated_member_hash)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
28
81
|
def measures_present
|
29
82
|
if self.measures.present?
|
30
83
|
self.measures.each do |measure|
|
@@ -69,9 +122,28 @@ module ::Rubiks
|
|
69
122
|
hash['name'] = self.name.to_s if self.name.present?
|
70
123
|
hash['dimensions'] = self.dimensions.map(&:to_hash) if self.dimensions.present?
|
71
124
|
hash['measures'] = self.measures.map(&:to_hash) if self.measures.present?
|
125
|
+
hash['calculated_members'] = self.calculated_members.map(&:to_hash) if self.calculated_members.present?
|
126
|
+
hash['date_dimension'] = self.date_dimension if self.date_dimension.present?
|
127
|
+
hash['person_dimension'] = self.person_dimension if self.person_dimension.present?
|
128
|
+
hash['count_measure'] = self.count_measure if self.count_measure.present?
|
129
|
+
hash['person_count_measure'] = self.person_count_measure if self.person_count_measure.present?
|
72
130
|
|
73
131
|
return hash
|
74
132
|
end
|
133
|
+
|
134
|
+
def to_xml(builder = nil)
|
135
|
+
builder = Builder::XmlMarkup.new(:indent => 2) if builder.nil?
|
136
|
+
|
137
|
+
attrs = Hash.new
|
138
|
+
attrs['name'] = self.name.titleize if self.name.present?
|
139
|
+
builder.cube(attrs) {
|
140
|
+
builder.table('name' => "view_#{self.name.tableize}") if self.name.present?
|
141
|
+
|
142
|
+
self.dimensions.each{ |dim| dim.to_xml(builder) } if self.dimensions.present?
|
143
|
+
self.measures.each{ |measure| measure.to_xml(builder) } if self.measures.present?
|
144
|
+
self.calculated_members.each{ |calculated_member| calculated_member.to_xml(builder) } if self.calculated_members.present?
|
145
|
+
}
|
146
|
+
end
|
75
147
|
end
|
76
148
|
|
77
149
|
end
|
@@ -37,6 +37,7 @@ module ::Rubiks
|
|
37
37
|
return if hierarchies_array.nil? || hierarchies_array.empty?
|
38
38
|
|
39
39
|
hierarchies_array.each do |hierarchy_hash|
|
40
|
+
hierarchy_hash['dimension'] = self.name if self.name.present?
|
40
41
|
self.hierarchies << ::Rubiks::Hierarchy.new_from_hash(hierarchy_hash)
|
41
42
|
end
|
42
43
|
end
|
@@ -49,6 +50,23 @@ module ::Rubiks
|
|
49
50
|
|
50
51
|
return hash
|
51
52
|
end
|
53
|
+
|
54
|
+
def to_xml(builder = nil)
|
55
|
+
builder = Builder::XmlMarkup.new(:indent => 2) if builder.nil?
|
56
|
+
|
57
|
+
attrs = self.to_hash
|
58
|
+
attrs.delete('hierarchies')
|
59
|
+
attrs['name'] = self.name.titleize if self.name.present?
|
60
|
+
attrs.keys.each do |key|
|
61
|
+
attrs[key.camelize(:lower)] = attrs.delete(key)
|
62
|
+
end
|
63
|
+
attrs['foreignKey'] = "#{self.name.underscore}_id" if self.name.present?
|
64
|
+
builder.dimension(attrs) {
|
65
|
+
self.hierarchies.each do |hier|
|
66
|
+
hier.to_xml(builder)
|
67
|
+
end if self.hierarchies.present?
|
68
|
+
}
|
69
|
+
end
|
52
70
|
end
|
53
71
|
|
54
72
|
end
|