rubiks 0.0.3 → 0.0.4

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 (45) hide show
  1. data/.rspec +4 -0
  2. data/.travis.yml +6 -0
  3. data/Gemfile +17 -2
  4. data/Guardfile +4 -4
  5. data/LICENSE.txt +1 -1
  6. data/README.md +9 -4
  7. data/Rakefile +3 -8
  8. data/lib/rubiks/nodes/annotated_node.rb +20 -0
  9. data/lib/rubiks/nodes/cube.rb +77 -0
  10. data/lib/rubiks/nodes/dimension.rb +54 -0
  11. data/lib/rubiks/nodes/hierarchy.rb +55 -0
  12. data/lib/rubiks/nodes/level.rb +29 -0
  13. data/lib/rubiks/nodes/measure.rb +66 -0
  14. data/lib/rubiks/nodes/schema.rb +61 -0
  15. data/lib/rubiks/nodes/validated_node.rb +47 -0
  16. data/lib/rubiks/version.rb +2 -2
  17. data/lib/rubiks.rb +6 -8
  18. data/rubiks.gemspec +5 -13
  19. data/spec/examples/mondrian_xml_example_spec.rb +91 -0
  20. data/spec/rubiks/nodes/annotated_node_spec.rb +24 -0
  21. data/spec/rubiks/nodes/cube_spec.rb +39 -0
  22. data/spec/rubiks/nodes/dimension_spec.rb +26 -0
  23. data/spec/rubiks/nodes/hierarchy_spec.rb +27 -0
  24. data/spec/rubiks/nodes/level_spec.rb +26 -0
  25. data/spec/rubiks/nodes/measure_spec.rb +31 -0
  26. data/spec/rubiks/nodes/schema_spec.rb +59 -0
  27. data/spec/rubiks/nodes/validated_node_spec.rb +49 -0
  28. data/spec/spec_helper.rb +22 -0
  29. data/spec/support/matchers/be_like.rb +24 -0
  30. data/spec/support/schema_context.rb +46 -0
  31. metadata +45 -144
  32. data/.simplecov +0 -6
  33. data/examples/finance/.rvmrc +0 -1
  34. data/examples/finance/Gemfile +0 -11
  35. data/examples/finance/app.rb +0 -14
  36. data/examples/finance/database.yml +0 -5
  37. data/examples/finance/domain.rb +0 -44
  38. data/examples/finance/setup +0 -46
  39. data/lib/rubiks/cube.rb +0 -95
  40. data/lib/rubiks/dimension.rb +0 -23
  41. data/lib/rubiks/hierarchy.rb +0 -15
  42. data/lib/rubiks/transformers/lookup_transformer.rb +0 -101
  43. data/test/rubiks/test_cube.rb +0 -15
  44. data/test/rubiks/test_dimension.rb +0 -11
  45. data/test/test_helper.rb +0 -6
@@ -1,44 +0,0 @@
1
- module Dimensions
2
- class Account < ActiveRecord::Base
3
- include Rubiks::Dimension
4
-
5
- hierarchy 'Asset/Liability' do
6
- level :asset_liability
7
- level :account_type
8
- end
9
-
10
- hierarchy 'Institution' do
11
- level :institution
12
- end
13
- end
14
-
15
- class Customer < ActiveRecord::Base
16
- include Rubiks::Dimension
17
-
18
- hierarchy 'Gender' do
19
- level :gender
20
- end
21
- end
22
-
23
- class Date < ActiveRecord::Base
24
- include Rubiks::Dimension
25
-
26
- hierarchy 'Date' do
27
- level :year
28
- level :quarter
29
- level :month
30
- end
31
- end
32
- end
33
-
34
- module Facts
35
- class AccountSnapshot < ActiveRecord::Base
36
- include Rubiks::Fact
37
-
38
- dimension :account
39
- dimension :customer
40
- dimension :date
41
-
42
- measure :balance
43
- end
44
- end
@@ -1,46 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # Requires PostgreSQL
3
- # Setup the finance_development DB
4
-
5
- require 'bundler'
6
- Bundler.require
7
-
8
- config = YAML.load_file('./database.yml')
9
-
10
- ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres'))
11
- ActiveRecord::Base.connection.create_database(config['database'])
12
-
13
- ActiveRecord::Base.establish_connection(config)
14
-
15
- ActiveRecord::Migration.create_table :accounts do |t|
16
- t.string :asset_liability
17
- t.string :account_type
18
- t.string :institution
19
- end
20
-
21
- ActiveRecord::Migration.create_table :dates do |t|
22
- t.integer :year
23
- t.integer :quarter
24
- t.integer :month
25
- t.integer :day
26
- end
27
-
28
- ActiveRecord::Migration.create_table :customers do |t|
29
- t.string :name
30
- t.string :gender
31
- end
32
-
33
- ActiveRecord::Migration.create_table :account_snapshots do |t|
34
- t.references :account
35
- t.references :date
36
- t.references :customer
37
- t.decimal :balance
38
- end
39
-
40
- require './domain'
41
-
42
- account = Dimensions::Account.create(:asset_liability => 'ASSET', :account_type => 'Savings', :institution => 'ACU - Awesome Credit Union')
43
- customer = Dimensions::Customer.create(:name => 'JohnnyT', :gender => 'Male')
44
- date = Dimesnions::Date.create(:year => 2012, :quarter => 4, :month => 11, :day => 31)
45
-
46
- Facts::AccountSnapshot.create(:account => account, :customer => customer, :date => date, :balance => 100.00)
data/lib/rubiks/cube.rb DELETED
@@ -1,95 +0,0 @@
1
- module Rubiks
2
- module Cube
3
- def self.included(klass)
4
- klass.extend Rubiks::Cube::ClassMethods
5
- end
6
-
7
- module ClassMethods
8
- def dimension(name)
9
- model_name = name.to_s
10
- dimensions << model_name
11
- belongs_to model_name, :class_name => "Dimensions::#{model_name.classify}"
12
- end
13
-
14
- def dimensions
15
- @dimensions ||= []
16
- end
17
-
18
- def measure(name)
19
- measures << name
20
- end
21
-
22
- def measures
23
- @measures ||= []
24
- end
25
- end
26
-
27
- def mdx(query)
28
- res = olap.execute(query)
29
- output = []
30
- output << res.column_full_names
31
- res.values.each{ |v| output << v }
32
- output.join("\n")
33
- end
34
-
35
- def to_s
36
- "#<#{self.class.name}>"
37
- end
38
-
39
- def inspect
40
- "#<#{self.class.name} dims: #{self.class.dimensions.inspect}>"
41
- end
42
-
43
-
44
- private
45
-
46
- def olap
47
- @olap ||= Mondrian::OLAP::Connection.create(mondrian_config)
48
- end
49
-
50
- def mondrian_config
51
- @mondrian_config ||= begin
52
- ar_config = ActiveRecord::Base.connection.config
53
-
54
- {
55
- :driver => ar_config[:adapter],
56
- :host => ar_config[:host],
57
- :database => ar_config[:database],
58
- :username => ar_config[:username],
59
- :password => ar_config[:password],
60
- :schema => mondrian_schema
61
- }
62
- end
63
- end
64
-
65
- def mondrian_schema
66
- rubiks_cube = self
67
- @mondrian_schema ||= Mondrian::OLAP::Schema.define do
68
- cube rubiks_cube.class.name do
69
- table rubiks_cube.class.table_name
70
-
71
- rubiks_cube.class.reflections.each do |name, reflection|
72
- dimension reflection.name.titleize, :foreign_key => reflection.foreign_key do
73
-
74
- reflection.class_name.constantize.hierarchies.each do |h|
75
- hierarchy :has_all => true, :primary_key => :id do
76
- table reflection.table_name
77
-
78
- h.levels.each do |l|
79
- level l.to_s.titleize, :column => l
80
- end
81
- end
82
- end
83
-
84
- end
85
- end
86
-
87
- rubiks_cube.class.measures.each do |m|
88
- measure m.to_s.titleize, :column => m, :aggregator => 'avg'
89
- end
90
- end
91
- end
92
- end
93
-
94
- end
95
- end
@@ -1,23 +0,0 @@
1
- module Rubiks
2
- module Dimension
3
- def self.included(klass)
4
- klass.extend Rubiks::Dimension::ClassMethods
5
- end
6
-
7
- module ClassMethods
8
- def hierarchy(name, &block)
9
- new_hierarchy = Hierarchy.new(name)
10
- new_hierarchy.instance_eval(&block) if block_given?
11
- hierarchies << new_hierarchy
12
- end
13
-
14
- def hierarchies
15
- @hierarchies ||= []
16
- end
17
- end
18
-
19
- def hierarchies
20
- self.class.hierarchies
21
- end
22
- end
23
- end
@@ -1,15 +0,0 @@
1
- module Rubiks
2
- class Hierarchy
3
- attr_accessor :name
4
- attr_reader :levels
5
-
6
- def initialize(name)
7
- @name = name
8
- @levels = []
9
- end
10
-
11
- def level(name)
12
- levels << name
13
- end
14
- end
15
- end
@@ -1,101 +0,0 @@
1
- module Rubiks
2
- module Transformers
3
- module LookupTransformer
4
- ##
5
- # Public instance methods
6
- #
7
- # Looks up the member or creates a new member if missing
8
- # @param[ActiveRecord Class] The class to lookup
9
- # @param[String] The external natural key (PK)
10
- # @return[Object] The found or created member
11
- def lookup_member(klass, natural_key)
12
- model_name = klass.name.underscore
13
- cache_key = "rubiks.lookup.#{model_name}.#{natural_key}"
14
-
15
- if id = cache.read(cache_key)
16
- klass.find_by_id(id)
17
-
18
- elsif existing_member = klass.where(natural_key_field => natural_key).first
19
- cache.write(cache_key, existing_member.id)
20
- existing_member
21
-
22
- else
23
- new_member = klass.new
24
- new_member[natural_key_field] = natural_key
25
-
26
- new_member.save!
27
- cache.write(cache_key, new_member.id)
28
- new_member
29
- end
30
- end
31
-
32
- # Looks up the surrogate key based off a natural key
33
- # @param[ActiveRecord Class] The class to lookup
34
- # @param[String] The external natural key (PK)
35
- # @return[Integer] The surrogate key of the found or created member
36
- def lookup(klass, natural_key)
37
- model_name = klass.name.underscore
38
- cache_key = "rubiks.lookup.#{model_name}.#{natural_key}"
39
-
40
- if id = cache.read(cache_key)
41
- id
42
-
43
- elsif existing_member = klass.where(natural_key_field => natural_key).first
44
- cache.write(cache_key, existing_member.id)
45
- existing_member.id
46
-
47
- else
48
- new_member = klass.new
49
- new_member[natural_key_field] = natural_key
50
-
51
- new_member.save!
52
- cache.write(cache_key, new_member.id)
53
- new_member.id
54
- end
55
- end
56
-
57
- def lookup_date(input)
58
- date = if input == :today
59
- Date.today
60
- elsif input == :yesterday
61
- 1.day.ago
62
- elsif input.kind_of? Integer
63
- Time.at(input)
64
- else
65
- Date.parse(input)
66
- end
67
-
68
- date.strftime('%Y%m%d').to_i
69
- rescue
70
- -1
71
- end
72
-
73
- def lookup_time(input)
74
- date = if input == :now
75
- Time.now
76
- elsif input.kind_of? Integer
77
- Time.at(input)
78
- else
79
- Date.parse(input)
80
- end
81
-
82
- # 1 HH MM SS 000
83
- # 11:59 PM = 1235959000
84
- date.strftime('1%H%M%S000').to_i
85
- rescue
86
- -1
87
- end
88
-
89
- def natural_key_field
90
- :natural_key
91
- end
92
-
93
- private
94
-
95
- def cache
96
- @cache ||= Rails.cache
97
- end
98
-
99
- end
100
- end
101
- end
@@ -1,15 +0,0 @@
1
- require 'test_helper'
2
-
3
- class TestCube < MiniTest::Unit::TestCase
4
- def setup
5
- @subject = Rubiks::Cube.new
6
- end
7
-
8
- def test_for_dimensions
9
- assert_respond_to @subject, :dimensions
10
- end
11
-
12
- def test_for_measures
13
- assert_respond_to @subject, :measures
14
- end
15
- end
@@ -1,11 +0,0 @@
1
- require 'test_helper'
2
-
3
- class TestDimension < MiniTest::Unit::TestCase
4
- def setup
5
- @subject = Rubiks::Dimension.new
6
- end
7
-
8
- def test_for_heirarchies
9
- assert_respond_to @subject, :hierarchies
10
- end
11
- end
data/test/test_helper.rb DELETED
@@ -1,6 +0,0 @@
1
- require 'minitest/spec'
2
- require 'minitest/autorun'
3
- require 'minitest/pride'
4
- require 'simplecov'
5
-
6
- require 'rubiks'