rubiks 0.0.4 → 0.0.5
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/.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
|
-
[]
|
4
|
-
[]
|
5
|
-
[][gem]
|
4
|
+
[][travis]
|
5
|
+
[][gemnasium]
|
6
|
+
[][codeclimate]
|
7
|
+
[][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
|