SlideShare a Scribd company logo
mondrian-olap 
JRuby library
Raimonds Simanovskis 
@rsim 
github.com/rsim
Mondrian! 
is nice…
But I don’t like 
Java and XML 
so much…
And I like! 
Ruby!
object-oriented 
dynamic 
programming language 
simple from outside 
powerful inside 
Yukihiro 
Matsumoto 
or “Matz”
What is! 
mondrian-olap! 
JRuby gem?
http://github.com/rsim/ 
mondrian-olap
Mondrian 3.x schema 
schema = Mondrian::OLAP::Schema.define do definition 
cube 'Sales' do 
table 'sales' 
dimension 'Customers', foreign_key: 'customer_id' do 
hierarchy has_all: true, all_member_name: 'All Customers', primary_key: 'id' do 
table 'customers' 
level 'Country', column: 'country', unique_members: true 
level 'State Province', column: 'state_province', unique_members: true 
level 'City', column: 'city', unique_members: false 
level 'Name', column: 'fullname', unique_members: false 
end 
end 
dimension 'Time', foreign_key: 'time_id', type: 'TimeDimension' do 
hierarchy has_all: false, primary_key: 'id' do 
table 'time' 
level 'Year', column: 'the_year', type: 'Numeric', unique_members: true, 
level_type: 'TimeYears' 
level 'Quarter', column: 'quarter', unique_members: false, 
level_type: 'TimeQuarters' 
level 'Month', column: 'month_of_year', type: 'Numeric', unique_members: false, 
level_type: 'TimeMonths' 
end 
end 
measure 'Unit Sales', column: 'unit_sales', aggregator: 'sum' 
measure 'Store Sales', column: 'store_sales', aggregator: 'sum' 
end 
end
Mondrian connection 
olap = Mondrian::OLAP::Connection.create( 
driver: 'mysql', 
host: 'localhost', 
database: 'mondrian_test', 
username: 'mondrian_user', 
password: 'secret', 
schema: schema 
)
MDX queries 
result = olap.execute <<-MDX 
SELECT {[Measures].[Unit Sales], [Measures].[Store Sales]} ON COLUMNS, 
{[Products].children} ON ROWS 
FROM [Sales] 
WHERE ([Time].[2010].[Q1], [Customers].[USA].[CA]) 
MDX 
! 
result.axes_count # => 2 
result.column_names # => ["Unit Sales", "Store Sales"] 
result.column_full_names # => ["[Measures].[Unit Sales]", 
# "[Measures].[Store Sales]"] 
result.row_names # => e.g. ["Drink", "Food", "Non-Consumable"] 
result.row_full_names # => e.g. ["[Products].[Drink]", "[Products]. 
[Food]", 
# "[Products].[Non-Consumable]"] 
result.values # => [[..., ...], [..., ...], [..., ...]] 
# (three rows, each row containing value for 
# "unit sales" and "store sales")
Query builder 
olap.from('Sales'). 
columns('[Measures].[Unit Sales]', '[Measures].[Store Sales]'). 
rows('[Products].children'). 
where('[Time].[2010].[Q1]', '[Customers].[USA].[CA]'). 
execute
Query builder 
olap.from('Sales'). 
with_member('[Measures].[ProfitPct]'). 
as('Val((Measures.[Store Sales] - Measures.[Store Cost]) / 
Measures.[Store Sales])', 
format_string: 'Percent'). 
columns('[Measures].[Store Sales]', '[Measures].[ProfitPct]'). 
rows('[Products].children'). 
crossjoin('[Customers].[Canada]', '[Customers].[USA]'). 
top_count(50, '[Measures].[Store Sales]'). 
where('[Time].[2010].[Q1]'). 
execute
Cube and member 
queries 
cube = olap.cube('Sales') 
cube.dimension_names # => ['Measures', 'Customers', 'Products', 
# 'Time'] 
cube.dimensions # => array of dimension objects 
cube.dimension('Customers') # => customers dimension object 
cube.dimension('Time').hierarchy_names # => ['Time', 'Time.Weekly'] 
cube.dimension('Time').hierarchies # => array of hierarchy objects 
cube.dimension('Customers').hierarchy # => default customers dimension hierarchy 
cube.dimension('Customers').hierarchy.level_names 
# => ['(All)', 'Country', 'State Province', 
# 'City', 'Name'] 
cube.dimension('Customers').hierarchy.levels 
# => array of hierarchy level objects 
cube.dimension('Customers').hierarchy.level('Country').members 
# => array of all level members 
cube.member('[Customers].[USA].[CA]') # => lookup member by full name 
cube.member('[Customers].[USA].[CA]').children 
# => get all children of member in deeper 
# hierarchy level 
cube.member('[Customers].[USA]').descendants_at_level('City') 
# => get all descendants of member in specified 
# hierarchy level
User defined 
MDX functions 
schema = Mondrian::OLAP::Schema.define do 
# ... cube definitions ... 
user_defined_function 'Factorial' do 
ruby do 
parameters :numeric 
returns :numeric 
def call(n) 
n <= 1 ? 1 : n * call(n - 1) 
end 
end 
end 
user_defined_function 'UpperName' do 
ruby do 
parameters :member 
returns :string 
syntax :property 
def call(member) 
member.getName.upcase 
end 
end 
end 
end
UDF in JavaScript 
schema = Mondrian::OLAP::Schema.define do 
# ... cube definitions ... 
user_defined_function 'Factorial' do 
javascript <<-JS 
function getParameterTypes() { 
return new Array( 
new mondrian.olap.type.NumericType()); 
} 
function getReturnType(parameterTypes) { 
return new mondrian.olap.type.NumericType(); 
} 
function execute(evaluator, arguments) { 
var n = arguments[0].evaluateScalar(evaluator); 
return factorial(n); 
} 
function factorial(n) { 
return n <= 1 ? 1 : n * factorial(n - 1); 
} 
JS 
end 
end
JavaScript is 
OK … but 
CoffeeScript 
is better!
Sample CoffeeScript 
# Assignment: 
number = 42 
opposite = true 
# Conditions: 
number = -42 if opposite 
# Functions: 
square = (x) -> x * x 
# Arrays: 
list = [1, 2, 3, 4, 5] 
# Objects: 
math = 
root: Math.sqrt 
square: square 
cube: (x) -> x * square x 
# Splats: 
race = (winner, runners...) -> 
print winner, runners 
# Existence: 
alert "I knew it!" if elvis? 
# Array comprehensions: 
cubes = (math.cube num for num in list)
UDF in CoffeeScript 
schema = Mondrian::OLAP::Schema.define do 
# ... cube definitions ... 
user_defined_function 'Factorial' do 
coffeescript <<-JS 
parameters: ["Numeric"] 
returns: "Numeric" 
execute: (n) -> 
if n <= 1 then 1 else n * @execute(n - 1) 
JS 
end 
end
Cell, property, member 
formatters in 
Ruby and CoffeeScript 
cell_formatter { ruby {|value| "%020d" % value} } 
property_formatter do 
ruby do |member, property_name, property_value| 
property_value.upcase 
end 
end 
member_formatter { ruby {|member| member.getName().upcase } } 
! 
cell_formatter do 
coffeescript <<-JS 
s = value.toString() 
s = "0" + s while s.length < 20 
s 
JS 
end 
member_formatter { coffeescript "member.getName().toUpperCase()" } 
property_formatter { coffeescript "propertyValue.toUpperCase()" }
Next idea:! 
More 
CoffeeScript
Next idea: 
Mondrian schema 
in CoffeeScript 
@Schema -> 
@Cube 'Sales', -> 
@Table 'sales' 
@Dimension 'Customers', foreignKey: 'customer_id', -> 
@Hierarchy hasAll: true, allMemberName: 'All Customers', primaryKey: 'id', -> 
@Table 'customers' 
@Level 'Country', column: 'country', uniqueMembers: true 
@Level 'State Province', column: 'state_province', uniqueMembers: true 
@Level 'City', column: 'city', uniqueMembers: false 
@Level 'Name', column: 'fullname', uniqueMembers: false 
@Dimension 'Time', foreignKey: 'time_id', type: 'TimeDimension', -> 
@Hierarchy hasAll: false, primaryKey: 'id', -> 
@Table 'time' 
@Level 'Year', column: 'the_year', type: 'Numeric', uniqueMembers: true,  
levelType: 'TimeYears' 
@Level 'Quarter', column: 'quarter', uniqueMembers: false,  
levelType: 'TimeQuarters' 
@Level 'Month', column: 'month_of_year', type: 'Numeric', uniqueMembers: false,  
levelType: 'TimeMonths' 
@Measure 'Unit Sales', column: 'unit_sales', aggregator: 'sum' 
@Measure 'Store Sales', column: 'store_sales', aggregator: 'sum'
Questions?

More Related Content

What's hot

Solid angular
Solid angularSolid angular
Solid angular
Nir Kaufman
 
Taming forms with React
Taming forms with ReactTaming forms with React
Taming forms with React
GreeceJS
 
AngularJS
AngularJSAngularJS
AngularJS
LearningTech
 
Optimizing Magento by Preloading Data
Optimizing Magento by Preloading DataOptimizing Magento by Preloading Data
Optimizing Magento by Preloading Data
Ivan Chepurnyi
 
날로 먹는 Django admin 활용
날로 먹는 Django admin 활용날로 먹는 Django admin 활용
날로 먹는 Django admin 활용
KyeongMook "Kay" Cha
 
Emberjs as a rails_developer
Emberjs as a rails_developer Emberjs as a rails_developer
Emberjs as a rails_developer
Sameera Gayan
 
Jquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript BasicsJquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript Basics
EPAM Systems
 
Django Admin: Widgetry & Witchery
Django Admin: Widgetry & WitcheryDjango Admin: Widgetry & Witchery
Django Admin: Widgetry & Witchery
Pamela Fox
 
WordPress Capabilities Magic
WordPress Capabilities MagicWordPress Capabilities Magic
WordPress Capabilities Magic
mannieschumpert
 
Angular js form validation shashi-19-7-16
Angular js form validation shashi-19-7-16Angular js form validation shashi-19-7-16
Angular js form validation shashi-19-7-16
Shashikant Bhongale
 
Get AngularJS Started!
Get AngularJS Started!Get AngularJS Started!
Get AngularJS Started!
Dzmitry Ivashutsin
 
Symfony CoP: Form component
Symfony CoP: Form componentSymfony CoP: Form component
Symfony CoP: Form component
Samuel ROZE
 
Working with Javascript in Rails
Working with Javascript in RailsWorking with Javascript in Rails
Working with Javascript in Rails
Seungkyun Nam
 
Oleksandr Masovets. Forms in Drupal. Drupal Camp Kyiv 2011
Oleksandr Masovets. Forms in Drupal. Drupal Camp Kyiv 2011Oleksandr Masovets. Forms in Drupal. Drupal Camp Kyiv 2011
Oleksandr Masovets. Forms in Drupal. Drupal Camp Kyiv 2011
Vlad Savitsky
 
Drupal Form Api
Drupal Form ApiDrupal Form Api
Drupal Form Api
Amit Kumar Singh
 
Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelpauldix
 
Gail villanueva add muscle to your wordpress site
Gail villanueva   add muscle to your wordpress siteGail villanueva   add muscle to your wordpress site
Gail villanueva add muscle to your wordpress sitereferences
 
Angular js form validation with ngmessages shashi-19-7-16
Angular js form validation with ngmessages shashi-19-7-16Angular js form validation with ngmessages shashi-19-7-16
Angular js form validation with ngmessages shashi-19-7-16
Shashikant Bhongale
 

What's hot (20)

Solid angular
Solid angularSolid angular
Solid angular
 
Taming forms with React
Taming forms with ReactTaming forms with React
Taming forms with React
 
AngularJS
AngularJSAngularJS
AngularJS
 
Template post
Template postTemplate post
Template post
 
Optimizing Magento by Preloading Data
Optimizing Magento by Preloading DataOptimizing Magento by Preloading Data
Optimizing Magento by Preloading Data
 
날로 먹는 Django admin 활용
날로 먹는 Django admin 활용날로 먹는 Django admin 활용
날로 먹는 Django admin 활용
 
Emberjs as a rails_developer
Emberjs as a rails_developer Emberjs as a rails_developer
Emberjs as a rails_developer
 
Jquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript BasicsJquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript Basics
 
Django Admin: Widgetry & Witchery
Django Admin: Widgetry & WitcheryDjango Admin: Widgetry & Witchery
Django Admin: Widgetry & Witchery
 
WordPress Capabilities Magic
WordPress Capabilities MagicWordPress Capabilities Magic
WordPress Capabilities Magic
 
Angular js form validation shashi-19-7-16
Angular js form validation shashi-19-7-16Angular js form validation shashi-19-7-16
Angular js form validation shashi-19-7-16
 
Get AngularJS Started!
Get AngularJS Started!Get AngularJS Started!
Get AngularJS Started!
 
Symfony CoP: Form component
Symfony CoP: Form componentSymfony CoP: Form component
Symfony CoP: Form component
 
Working with Javascript in Rails
Working with Javascript in RailsWorking with Javascript in Rails
Working with Javascript in Rails
 
Oleksandr Masovets. Forms in Drupal. Drupal Camp Kyiv 2011
Oleksandr Masovets. Forms in Drupal. Drupal Camp Kyiv 2011Oleksandr Masovets. Forms in Drupal. Drupal Camp Kyiv 2011
Oleksandr Masovets. Forms in Drupal. Drupal Camp Kyiv 2011
 
Drupal Form Api
Drupal Form ApiDrupal Form Api
Drupal Form Api
 
Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModel
 
Gail villanueva add muscle to your wordpress site
Gail villanueva   add muscle to your wordpress siteGail villanueva   add muscle to your wordpress site
Gail villanueva add muscle to your wordpress site
 
HTML Form Part 1
HTML Form Part 1HTML Form Part 1
HTML Form Part 1
 
Angular js form validation with ngmessages shashi-19-7-16
Angular js form validation with ngmessages shashi-19-7-16Angular js form validation with ngmessages shashi-19-7-16
Angular js form validation with ngmessages shashi-19-7-16
 

Similar to mondrian-olap JRuby library

Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasminePaulo Ragonha
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web Apps
Mike Subelsky
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
rstankov
 
Multidimensional Data Analysis with Ruby (sample)
Multidimensional Data Analysis with Ruby (sample)Multidimensional Data Analysis with Ruby (sample)
Multidimensional Data Analysis with Ruby (sample)Raimonds Simanovskis
 
The Future of Rubymotion
The Future of RubymotionThe Future of Rubymotion
The Future of RubymotionClay Allsopp
 
Why ruby
Why rubyWhy ruby
Why ruby
rstankov
 
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Raimonds Simanovskis
 
Rails World 2023: Powerful Rails Features You Might Not Know
Rails World 2023: Powerful Rails Features You Might Not KnowRails World 2023: Powerful Rails Features You Might Not Know
Rails World 2023: Powerful Rails Features You Might Not Know
Chris Oliver
 
SOLID Ruby, SOLID Rails
SOLID Ruby, SOLID RailsSOLID Ruby, SOLID Rails
SOLID Ruby, SOLID Rails
Jens-Christian Fischer
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends旻琦 潘
 
A piece of sugar in your client-side development
A piece of sugar in your client-side developmentA piece of sugar in your client-side development
A piece of sugar in your client-side development
Nicolas Blanco
 
Functional programming with Ruby - can make you look smart
Functional programming with Ruby - can make you look smartFunctional programming with Ruby - can make you look smart
Functional programming with Ruby - can make you look smart
Chen Fisher
 
Seu primeiro app Android e iOS com Compose Multiplatform
Seu primeiro app Android e iOS com Compose MultiplatformSeu primeiro app Android e iOS com Compose Multiplatform
Seu primeiro app Android e iOS com Compose Multiplatform
Nelson Glauber Leal
 
Ruby on Rails testing with Rspec
Ruby on Rails testing with RspecRuby on Rails testing with Rspec
Ruby on Rails testing with Rspec
Bunlong Van
 
Profiling Mondrian MDX Requests in a Production Environment
Profiling Mondrian MDX Requests in a Production EnvironmentProfiling Mondrian MDX Requests in a Production Environment
Profiling Mondrian MDX Requests in a Production Environment
Raimonds Simanovskis
 
Say Goodbye to Procedural Programming - Nick Sutterer
Say Goodbye to Procedural Programming - Nick SuttererSay Goodbye to Procedural Programming - Nick Sutterer
Say Goodbye to Procedural Programming - Nick Sutterer
Ruby Meditation
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design Patterns
Iván Fernández Perea
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...Fabio Franzini
 
Integrating SAP the Java EE Way - JBoss One Day talk 2012
Integrating SAP the Java EE Way - JBoss One Day talk 2012Integrating SAP the Java EE Way - JBoss One Day talk 2012
Integrating SAP the Java EE Way - JBoss One Day talk 2012
hwilming
 
Emerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the HorizonEmerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the Horizon
Alex Payne
 

Similar to mondrian-olap JRuby library (20)

Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web Apps
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
 
Multidimensional Data Analysis with Ruby (sample)
Multidimensional Data Analysis with Ruby (sample)Multidimensional Data Analysis with Ruby (sample)
Multidimensional Data Analysis with Ruby (sample)
 
The Future of Rubymotion
The Future of RubymotionThe Future of Rubymotion
The Future of Rubymotion
 
Why ruby
Why rubyWhy ruby
Why ruby
 
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
 
Rails World 2023: Powerful Rails Features You Might Not Know
Rails World 2023: Powerful Rails Features You Might Not KnowRails World 2023: Powerful Rails Features You Might Not Know
Rails World 2023: Powerful Rails Features You Might Not Know
 
SOLID Ruby, SOLID Rails
SOLID Ruby, SOLID RailsSOLID Ruby, SOLID Rails
SOLID Ruby, SOLID Rails
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
A piece of sugar in your client-side development
A piece of sugar in your client-side developmentA piece of sugar in your client-side development
A piece of sugar in your client-side development
 
Functional programming with Ruby - can make you look smart
Functional programming with Ruby - can make you look smartFunctional programming with Ruby - can make you look smart
Functional programming with Ruby - can make you look smart
 
Seu primeiro app Android e iOS com Compose Multiplatform
Seu primeiro app Android e iOS com Compose MultiplatformSeu primeiro app Android e iOS com Compose Multiplatform
Seu primeiro app Android e iOS com Compose Multiplatform
 
Ruby on Rails testing with Rspec
Ruby on Rails testing with RspecRuby on Rails testing with Rspec
Ruby on Rails testing with Rspec
 
Profiling Mondrian MDX Requests in a Production Environment
Profiling Mondrian MDX Requests in a Production EnvironmentProfiling Mondrian MDX Requests in a Production Environment
Profiling Mondrian MDX Requests in a Production Environment
 
Say Goodbye to Procedural Programming - Nick Sutterer
Say Goodbye to Procedural Programming - Nick SuttererSay Goodbye to Procedural Programming - Nick Sutterer
Say Goodbye to Procedural Programming - Nick Sutterer
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design Patterns
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
Integrating SAP the Java EE Way - JBoss One Day talk 2012
Integrating SAP the Java EE Way - JBoss One Day talk 2012Integrating SAP the Java EE Way - JBoss One Day talk 2012
Integrating SAP the Java EE Way - JBoss One Day talk 2012
 
Emerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the HorizonEmerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the Horizon
 

More from Raimonds Simanovskis

Analyze and Visualize Git Log for Fun and Profit - DevTernity 2015
Analyze and Visualize Git Log for Fun and Profit - DevTernity 2015Analyze and Visualize Git Log for Fun and Profit - DevTernity 2015
Analyze and Visualize Git Log for Fun and Profit - DevTernity 2015
Raimonds Simanovskis
 
Data Warehouses and Multi-Dimensional Data Analysis
Data Warehouses and Multi-Dimensional Data AnalysisData Warehouses and Multi-Dimensional Data Analysis
Data Warehouses and Multi-Dimensional Data Analysis
Raimonds Simanovskis
 
eazyBI Overview - Embedding Mondrian in other applications
eazyBI Overview - Embedding Mondrian in other applicationseazyBI Overview - Embedding Mondrian in other applications
eazyBI Overview - Embedding Mondrian in other applications
Raimonds Simanovskis
 
Atvērto datu izmantošanas pieredze Latvijā
Atvērto datu izmantošanas pieredze LatvijāAtvērto datu izmantošanas pieredze Latvijā
Atvērto datu izmantošanas pieredze Latvijā
Raimonds Simanovskis
 
JavaScript Unit Testing with Jasmine
JavaScript Unit Testing with JasmineJavaScript Unit Testing with Jasmine
JavaScript Unit Testing with Jasmine
Raimonds Simanovskis
 
JRuby - Programmer's Best Friend on JVM
JRuby - Programmer's Best Friend on JVMJRuby - Programmer's Best Friend on JVM
JRuby - Programmer's Best Friend on JVM
Raimonds Simanovskis
 
Agile Operations or How to sleep better at night
Agile Operations or How to sleep better at nightAgile Operations or How to sleep better at night
Agile Operations or How to sleep better at night
Raimonds Simanovskis
 
TDD - Why and How?
TDD - Why and How?TDD - Why and How?
TDD - Why and How?
Raimonds Simanovskis
 
Analyze and Visualize Git Log for Fun and Profit
Analyze and Visualize Git Log for Fun and ProfitAnalyze and Visualize Git Log for Fun and Profit
Analyze and Visualize Git Log for Fun and Profit
Raimonds Simanovskis
 
PL/SQL Unit Testing Can Be Fun
PL/SQL Unit Testing Can Be FunPL/SQL Unit Testing Can Be Fun
PL/SQL Unit Testing Can Be Fun
Raimonds Simanovskis
 
opendata.lv Case Study - Promote Open Data with Analytics and Visualizations
opendata.lv Case Study - Promote Open Data with Analytics and Visualizationsopendata.lv Case Study - Promote Open Data with Analytics and Visualizations
opendata.lv Case Study - Promote Open Data with Analytics and Visualizations
Raimonds Simanovskis
 
Extending Oracle E-Business Suite with Ruby on Rails
Extending Oracle E-Business Suite with Ruby on RailsExtending Oracle E-Business Suite with Ruby on Rails
Extending Oracle E-Business Suite with Ruby on Rails
Raimonds Simanovskis
 
RailsWayCon: Multidimensional Data Analysis with JRuby
RailsWayCon: Multidimensional Data Analysis with JRubyRailsWayCon: Multidimensional Data Analysis with JRuby
RailsWayCon: Multidimensional Data Analysis with JRuby
Raimonds Simanovskis
 
Why Every Tester Should Learn Ruby
Why Every Tester Should Learn RubyWhy Every Tester Should Learn Ruby
Why Every Tester Should Learn Ruby
Raimonds Simanovskis
 
Multidimensional Data Analysis with JRuby
Multidimensional Data Analysis with JRubyMultidimensional Data Analysis with JRuby
Multidimensional Data Analysis with JRuby
Raimonds Simanovskis
 
Rails on Oracle 2011
Rails on Oracle 2011Rails on Oracle 2011
Rails on Oracle 2011
Raimonds Simanovskis
 
Rails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript using CoffeeScript, Backbone.js and JasmineRails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript using CoffeeScript, Backbone.js and JasmineRaimonds Simanovskis
 
How to Adopt Agile at Your Organization
How to Adopt Agile at Your OrganizationHow to Adopt Agile at Your Organization
How to Adopt Agile at Your OrganizationRaimonds Simanovskis
 
Fast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleFast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleRaimonds Simanovskis
 

More from Raimonds Simanovskis (20)

Analyze and Visualize Git Log for Fun and Profit - DevTernity 2015
Analyze and Visualize Git Log for Fun and Profit - DevTernity 2015Analyze and Visualize Git Log for Fun and Profit - DevTernity 2015
Analyze and Visualize Git Log for Fun and Profit - DevTernity 2015
 
Data Warehouses and Multi-Dimensional Data Analysis
Data Warehouses and Multi-Dimensional Data AnalysisData Warehouses and Multi-Dimensional Data Analysis
Data Warehouses and Multi-Dimensional Data Analysis
 
eazyBI Overview - Embedding Mondrian in other applications
eazyBI Overview - Embedding Mondrian in other applicationseazyBI Overview - Embedding Mondrian in other applications
eazyBI Overview - Embedding Mondrian in other applications
 
Atvērto datu izmantošanas pieredze Latvijā
Atvērto datu izmantošanas pieredze LatvijāAtvērto datu izmantošanas pieredze Latvijā
Atvērto datu izmantošanas pieredze Latvijā
 
JavaScript Unit Testing with Jasmine
JavaScript Unit Testing with JasmineJavaScript Unit Testing with Jasmine
JavaScript Unit Testing with Jasmine
 
JRuby - Programmer's Best Friend on JVM
JRuby - Programmer's Best Friend on JVMJRuby - Programmer's Best Friend on JVM
JRuby - Programmer's Best Friend on JVM
 
Agile Operations or How to sleep better at night
Agile Operations or How to sleep better at nightAgile Operations or How to sleep better at night
Agile Operations or How to sleep better at night
 
TDD - Why and How?
TDD - Why and How?TDD - Why and How?
TDD - Why and How?
 
Analyze and Visualize Git Log for Fun and Profit
Analyze and Visualize Git Log for Fun and ProfitAnalyze and Visualize Git Log for Fun and Profit
Analyze and Visualize Git Log for Fun and Profit
 
PL/SQL Unit Testing Can Be Fun
PL/SQL Unit Testing Can Be FunPL/SQL Unit Testing Can Be Fun
PL/SQL Unit Testing Can Be Fun
 
opendata.lv Case Study - Promote Open Data with Analytics and Visualizations
opendata.lv Case Study - Promote Open Data with Analytics and Visualizationsopendata.lv Case Study - Promote Open Data with Analytics and Visualizations
opendata.lv Case Study - Promote Open Data with Analytics and Visualizations
 
Extending Oracle E-Business Suite with Ruby on Rails
Extending Oracle E-Business Suite with Ruby on RailsExtending Oracle E-Business Suite with Ruby on Rails
Extending Oracle E-Business Suite with Ruby on Rails
 
RailsWayCon: Multidimensional Data Analysis with JRuby
RailsWayCon: Multidimensional Data Analysis with JRubyRailsWayCon: Multidimensional Data Analysis with JRuby
RailsWayCon: Multidimensional Data Analysis with JRuby
 
Why Every Tester Should Learn Ruby
Why Every Tester Should Learn RubyWhy Every Tester Should Learn Ruby
Why Every Tester Should Learn Ruby
 
Multidimensional Data Analysis with JRuby
Multidimensional Data Analysis with JRubyMultidimensional Data Analysis with JRuby
Multidimensional Data Analysis with JRuby
 
Rails on Oracle 2011
Rails on Oracle 2011Rails on Oracle 2011
Rails on Oracle 2011
 
Rails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript using CoffeeScript, Backbone.js and JasmineRails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
 
How to Adopt Agile at Your Organization
How to Adopt Agile at Your OrganizationHow to Adopt Agile at Your Organization
How to Adopt Agile at Your Organization
 
PL/SQL Unit Testing Can Be Fun!
PL/SQL Unit Testing Can Be Fun!PL/SQL Unit Testing Can Be Fun!
PL/SQL Unit Testing Can Be Fun!
 
Fast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleFast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on Oracle
 

Recently uploaded

Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
Bhaskar Mitra
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
Abida Shariff
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
RTTS
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Tobias Schneck
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
BookNet Canada
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Jeffrey Haguewood
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
Elena Simperl
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Product School
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 

Recently uploaded (20)

Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 

mondrian-olap JRuby library

  • 2. Raimonds Simanovskis @rsim github.com/rsim
  • 4. But I don’t like Java and XML so much…
  • 5. And I like! Ruby!
  • 6. object-oriented dynamic programming language simple from outside powerful inside Yukihiro Matsumoto or “Matz”
  • 7.
  • 8.
  • 11. Mondrian 3.x schema schema = Mondrian::OLAP::Schema.define do definition cube 'Sales' do table 'sales' dimension 'Customers', foreign_key: 'customer_id' do hierarchy has_all: true, all_member_name: 'All Customers', primary_key: 'id' do table 'customers' level 'Country', column: 'country', unique_members: true level 'State Province', column: 'state_province', unique_members: true level 'City', column: 'city', unique_members: false level 'Name', column: 'fullname', unique_members: false end end dimension 'Time', foreign_key: 'time_id', type: 'TimeDimension' do hierarchy has_all: false, primary_key: 'id' do table 'time' level 'Year', column: 'the_year', type: 'Numeric', unique_members: true, level_type: 'TimeYears' level 'Quarter', column: 'quarter', unique_members: false, level_type: 'TimeQuarters' level 'Month', column: 'month_of_year', type: 'Numeric', unique_members: false, level_type: 'TimeMonths' end end measure 'Unit Sales', column: 'unit_sales', aggregator: 'sum' measure 'Store Sales', column: 'store_sales', aggregator: 'sum' end end
  • 12. Mondrian connection olap = Mondrian::OLAP::Connection.create( driver: 'mysql', host: 'localhost', database: 'mondrian_test', username: 'mondrian_user', password: 'secret', schema: schema )
  • 13. MDX queries result = olap.execute <<-MDX SELECT {[Measures].[Unit Sales], [Measures].[Store Sales]} ON COLUMNS, {[Products].children} ON ROWS FROM [Sales] WHERE ([Time].[2010].[Q1], [Customers].[USA].[CA]) MDX ! result.axes_count # => 2 result.column_names # => ["Unit Sales", "Store Sales"] result.column_full_names # => ["[Measures].[Unit Sales]", # "[Measures].[Store Sales]"] result.row_names # => e.g. ["Drink", "Food", "Non-Consumable"] result.row_full_names # => e.g. ["[Products].[Drink]", "[Products]. [Food]", # "[Products].[Non-Consumable]"] result.values # => [[..., ...], [..., ...], [..., ...]] # (three rows, each row containing value for # "unit sales" and "store sales")
  • 14. Query builder olap.from('Sales'). columns('[Measures].[Unit Sales]', '[Measures].[Store Sales]'). rows('[Products].children'). where('[Time].[2010].[Q1]', '[Customers].[USA].[CA]'). execute
  • 15. Query builder olap.from('Sales'). with_member('[Measures].[ProfitPct]'). as('Val((Measures.[Store Sales] - Measures.[Store Cost]) / Measures.[Store Sales])', format_string: 'Percent'). columns('[Measures].[Store Sales]', '[Measures].[ProfitPct]'). rows('[Products].children'). crossjoin('[Customers].[Canada]', '[Customers].[USA]'). top_count(50, '[Measures].[Store Sales]'). where('[Time].[2010].[Q1]'). execute
  • 16. Cube and member queries cube = olap.cube('Sales') cube.dimension_names # => ['Measures', 'Customers', 'Products', # 'Time'] cube.dimensions # => array of dimension objects cube.dimension('Customers') # => customers dimension object cube.dimension('Time').hierarchy_names # => ['Time', 'Time.Weekly'] cube.dimension('Time').hierarchies # => array of hierarchy objects cube.dimension('Customers').hierarchy # => default customers dimension hierarchy cube.dimension('Customers').hierarchy.level_names # => ['(All)', 'Country', 'State Province', # 'City', 'Name'] cube.dimension('Customers').hierarchy.levels # => array of hierarchy level objects cube.dimension('Customers').hierarchy.level('Country').members # => array of all level members cube.member('[Customers].[USA].[CA]') # => lookup member by full name cube.member('[Customers].[USA].[CA]').children # => get all children of member in deeper # hierarchy level cube.member('[Customers].[USA]').descendants_at_level('City') # => get all descendants of member in specified # hierarchy level
  • 17. User defined MDX functions schema = Mondrian::OLAP::Schema.define do # ... cube definitions ... user_defined_function 'Factorial' do ruby do parameters :numeric returns :numeric def call(n) n <= 1 ? 1 : n * call(n - 1) end end end user_defined_function 'UpperName' do ruby do parameters :member returns :string syntax :property def call(member) member.getName.upcase end end end end
  • 18. UDF in JavaScript schema = Mondrian::OLAP::Schema.define do # ... cube definitions ... user_defined_function 'Factorial' do javascript <<-JS function getParameterTypes() { return new Array( new mondrian.olap.type.NumericType()); } function getReturnType(parameterTypes) { return new mondrian.olap.type.NumericType(); } function execute(evaluator, arguments) { var n = arguments[0].evaluateScalar(evaluator); return factorial(n); } function factorial(n) { return n <= 1 ? 1 : n * factorial(n - 1); } JS end end
  • 19. JavaScript is OK … but CoffeeScript is better!
  • 20.
  • 21. Sample CoffeeScript # Assignment: number = 42 opposite = true # Conditions: number = -42 if opposite # Functions: square = (x) -> x * x # Arrays: list = [1, 2, 3, 4, 5] # Objects: math = root: Math.sqrt square: square cube: (x) -> x * square x # Splats: race = (winner, runners...) -> print winner, runners # Existence: alert "I knew it!" if elvis? # Array comprehensions: cubes = (math.cube num for num in list)
  • 22. UDF in CoffeeScript schema = Mondrian::OLAP::Schema.define do # ... cube definitions ... user_defined_function 'Factorial' do coffeescript <<-JS parameters: ["Numeric"] returns: "Numeric" execute: (n) -> if n <= 1 then 1 else n * @execute(n - 1) JS end end
  • 23. Cell, property, member formatters in Ruby and CoffeeScript cell_formatter { ruby {|value| "%020d" % value} } property_formatter do ruby do |member, property_name, property_value| property_value.upcase end end member_formatter { ruby {|member| member.getName().upcase } } ! cell_formatter do coffeescript <<-JS s = value.toString() s = "0" + s while s.length < 20 s JS end member_formatter { coffeescript "member.getName().toUpperCase()" } property_formatter { coffeescript "propertyValue.toUpperCase()" }
  • 24. Next idea:! More CoffeeScript
  • 25. Next idea: Mondrian schema in CoffeeScript @Schema -> @Cube 'Sales', -> @Table 'sales' @Dimension 'Customers', foreignKey: 'customer_id', -> @Hierarchy hasAll: true, allMemberName: 'All Customers', primaryKey: 'id', -> @Table 'customers' @Level 'Country', column: 'country', uniqueMembers: true @Level 'State Province', column: 'state_province', uniqueMembers: true @Level 'City', column: 'city', uniqueMembers: false @Level 'Name', column: 'fullname', uniqueMembers: false @Dimension 'Time', foreignKey: 'time_id', type: 'TimeDimension', -> @Hierarchy hasAll: false, primaryKey: 'id', -> @Table 'time' @Level 'Year', column: 'the_year', type: 'Numeric', uniqueMembers: true, levelType: 'TimeYears' @Level 'Quarter', column: 'quarter', uniqueMembers: false, levelType: 'TimeQuarters' @Level 'Month', column: 'month_of_year', type: 'Numeric', uniqueMembers: false, levelType: 'TimeMonths' @Measure 'Unit Sales', column: 'unit_sales', aggregator: 'sum' @Measure 'Store Sales', column: 'store_sales', aggregator: 'sum'