mondrian-olap 0.3.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/Changelog.md +38 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +302 -0
  5. data/VERSION +1 -1
  6. data/lib/mondrian/jars/commons-collections-3.2.jar +0 -0
  7. data/lib/mondrian/jars/commons-logging-1.1.1.jar +0 -0
  8. data/lib/mondrian/jars/commons-math-1.1.jar +0 -0
  9. data/lib/mondrian/jars/eigenbase-properties-1.1.2.jar +0 -0
  10. data/lib/mondrian/jars/eigenbase-resgen-1.3.1.jar +0 -0
  11. data/lib/mondrian/jars/eigenbase-xom-1.3.1.jar +0 -0
  12. data/lib/mondrian/jars/{javacup.jar → javacup-10k.jar} +0 -0
  13. data/lib/mondrian/jars/log4j-1.2.14.jar +0 -0
  14. data/lib/mondrian/jars/mondrian.jar +0 -0
  15. data/lib/mondrian/jars/olap4j-1.0.1.539.jar +0 -0
  16. data/lib/mondrian/olap.rb +2 -1
  17. data/lib/mondrian/olap/connection.rb +163 -32
  18. data/lib/mondrian/olap/cube.rb +163 -24
  19. data/lib/mondrian/olap/error.rb +57 -0
  20. data/lib/mondrian/olap/query.rb +52 -17
  21. data/lib/mondrian/olap/result.rb +298 -6
  22. data/lib/mondrian/olap/schema.rb +220 -29
  23. data/lib/mondrian/olap/schema_element.rb +31 -11
  24. data/lib/mondrian/olap/schema_udf.rb +331 -0
  25. data/lib/mondrian/olap/version.rb +5 -0
  26. data/spec/connection_role_spec.rb +130 -0
  27. data/spec/connection_spec.rb +36 -1
  28. data/spec/cube_spec.rb +137 -7
  29. data/spec/fixtures/MondrianTest.xml +4 -4
  30. data/spec/mondrian_spec.rb +53 -0
  31. data/spec/query_spec.rb +294 -11
  32. data/spec/rake_tasks.rb +8 -8
  33. data/spec/schema_definition_spec.rb +845 -26
  34. data/spec/spec_helper.rb +26 -17
  35. data/spec/support/matchers/be_like.rb +2 -2
  36. metadata +296 -237
  37. data/.rspec +0 -2
  38. data/Gemfile +0 -18
  39. data/README.rdoc +0 -221
  40. data/RUNNING_TESTS.rdoc +0 -66
  41. data/Rakefile +0 -46
  42. data/lib/mondrian/jars/commons-collections-3.1.jar +0 -0
  43. data/lib/mondrian/jars/commons-logging-1.0.4.jar +0 -0
  44. data/lib/mondrian/jars/commons-math-1.0.jar +0 -0
  45. data/lib/mondrian/jars/eigenbase-properties.jar +0 -0
  46. data/lib/mondrian/jars/eigenbase-resgen.jar +0 -0
  47. data/lib/mondrian/jars/eigenbase-xom.jar +0 -0
  48. data/lib/mondrian/jars/log4j-1.2.8.jar +0 -0
  49. data/lib/mondrian/jars/olap4j.jar +0 -0
  50. data/mondrian-olap.gemspec +0 -126
@@ -1,9 +1,7 @@
1
- require 'nokogiri'
2
-
3
1
  module Mondrian
4
2
  module OLAP
5
3
  class SchemaElement
6
- def initialize(name = nil, attributes = {}, &block)
4
+ def initialize(name = nil, attributes = {}, parent = nil, &block)
7
5
  # if just attributes hash provided
8
6
  if name.is_a?(Hash) && attributes == {}
9
7
  attributes = name
@@ -12,7 +10,14 @@ module Mondrian
12
10
  @attributes = {}
13
11
  if name
14
12
  if self.class.content
15
- @content = name
13
+ if attributes.is_a?(Hash)
14
+ @content = name
15
+ else
16
+ # used for Annotation element where both name and content is given as arguments
17
+ @attributes[:name] = name
18
+ @content = attributes
19
+ attributes = {}
20
+ end
16
21
  else
17
22
  @attributes[:name] = name
18
23
  end
@@ -21,8 +26,12 @@ module Mondrian
21
26
  self.class.elements.each do |element|
22
27
  instance_variable_set("@#{pluralize(element)}", [])
23
28
  end
29
+ # extract annotations from options
30
+ if @attributes[:annotations] && self.class.elements.include?(:annotations)
31
+ annotations @attributes.delete(:annotations)
32
+ end
24
33
  @xml_fragments = []
25
- instance_eval &block if block
34
+ instance_eval(&block) if block
26
35
  end
27
36
 
28
37
  def self.attributes(*names)
@@ -54,10 +63,11 @@ module Mondrian
54
63
  @elements.concat(names)
55
64
 
56
65
  names.each do |name|
66
+ next if name == :xml
57
67
  attr_reader pluralize(name).to_sym
58
68
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
59
69
  def #{name}(name=nil, attributes = {}, &block)
60
- @#{pluralize(name)} << Schema::#{camel_case(name)}.new(name, attributes, &block)
70
+ @#{pluralize(name)} << Schema::#{camel_case(name)}.new(name, attributes, self, &block)
61
71
  end
62
72
  RUBY
63
73
  end
@@ -78,7 +88,7 @@ module Mondrian
78
88
 
79
89
  def to_xml(options={})
80
90
  options[:upcase_data_dictionary] = @upcase_data_dictionary unless @upcase_data_dictionary.nil?
81
- Nokogiri::XML::Builder.new do |xml|
91
+ Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
82
92
  add_to_xml(xml, options)
83
93
  end.to_xml
84
94
  end
@@ -90,16 +100,26 @@ module Mondrian
90
100
  xml.send(tag_name(self.class.name), @content, xmlized_attributes(options))
91
101
  else
92
102
  xml.send(tag_name(self.class.name), xmlized_attributes(options)) do
103
+ xml_fragments_added = false
93
104
  self.class.elements.each do |element|
94
- instance_variable_get("@#{pluralize(element)}").each {|item| item.add_to_xml(xml, options)}
95
- end
96
- @xml_fragments.each do |xml_fragment|
97
- xml.send(:insert, Nokogiri::XML::DocumentFragment.parse(xml_fragment))
105
+ if element == :xml
106
+ add_xml_fragments(xml)
107
+ xml_fragments_added = true
108
+ else
109
+ instance_variable_get("@#{pluralize(element)}").each {|item| item.add_to_xml(xml, options)}
110
+ end
98
111
  end
112
+ add_xml_fragments(xml) unless xml_fragments_added
99
113
  end
100
114
  end
101
115
  end
102
116
 
117
+ def add_xml_fragments(xml)
118
+ @xml_fragments.each do |xml_fragment|
119
+ xml.send(:insert, Nokogiri::XML::DocumentFragment.parse(xml_fragment))
120
+ end
121
+ end
122
+
103
123
  private
104
124
 
105
125
  def xmlized_attributes(options)
@@ -0,0 +1,331 @@
1
+ require 'jruby/core_ext'
2
+
3
+ module Mondrian
4
+ module OLAP
5
+ class Schema < SchemaElement
6
+
7
+ def user_defined_cell_formatter(name, &block)
8
+ CellFormatter.new(name, &block)
9
+ end
10
+
11
+ module ScriptElements
12
+ def javascript(text)
13
+ script text, :language => 'JavaScript'
14
+ end
15
+
16
+ private
17
+
18
+ def coffeescript_function(arguments_string, text)
19
+ # construct function to ensure that last expression is returned
20
+ coffee_text = "#{arguments_string} ->\n" << text.gsub(/^/,' ')
21
+ javascript_text = CoffeeScript.compile(coffee_text, :bare => true)
22
+ # remove function definition first and last lines
23
+ javascript_text = javascript_text.strip.lines.to_a[1..-2].join
24
+ javascript javascript_text
25
+ end
26
+
27
+ def ruby(*options, &block)
28
+ udf_class_name = if options.include?(:shared)
29
+ "#{name.capitalize}Udf"
30
+ end
31
+ if udf_class_name && self.class.const_defined?(udf_class_name)
32
+ udf_class = self.class.const_get(udf_class_name)
33
+ else
34
+ udf_class = Class.new(RubyUdfBase)
35
+ self.class.const_set(udf_class_name, udf_class) if udf_class_name
36
+ end
37
+ udf_class.function_name = name
38
+ udf_class.class_eval(&block)
39
+ udf_java_class = udf_class.become_java!(false)
40
+
41
+ class_name udf_java_class.getName
42
+ end
43
+
44
+ def ruby_formatter(options, interface_class, method, signature, &block)
45
+ formatter_class_name = if options.include?(:shared) && @attributes[:name]
46
+ ruby_formatter_name_to_class_name(@attributes[:name])
47
+ end
48
+ if formatter_class_name && self.class.const_defined?(formatter_class_name)
49
+ formatter_class = self.class.const_get(formatter_class_name)
50
+ else
51
+ formatter_class = Class.new
52
+ self.class.const_set(formatter_class_name, formatter_class) if formatter_class_name
53
+ end
54
+
55
+ formatter_class.class_eval do
56
+ include interface_class
57
+ define_method method, &block
58
+ add_method_signature(method, signature)
59
+ end
60
+ formatter_java_class = formatter_class.become_java!(false)
61
+ class_name formatter_java_class.getName
62
+ end
63
+
64
+ def ruby_formatter_name_to_class_name(name)
65
+ # upcase just first character
66
+ "#{name.sub(/\A./){|m| m.upcase}}Udf"
67
+ end
68
+
69
+ def ruby_formatter_java_class_name(name)
70
+ "rubyobj.#{self.class.name.gsub('::','.')}.#{ruby_formatter_name_to_class_name(name)}"
71
+ end
72
+
73
+ end
74
+
75
+ class UserDefinedFunction < SchemaElement
76
+ include ScriptElements
77
+ attributes :name, # Name with which the user-defined function will be referenced in MDX expressions.
78
+ # Name of the class which implemenets this user-defined function.
79
+ # Must implement the mondrian.spi.UserDefinedFunction interface.
80
+ :class_name
81
+ elements :script
82
+
83
+ def coffeescript(text)
84
+ coffee_text = "__udf__ = {\n" << text << "}\n"
85
+ javascript_text = CoffeeScript.compile(coffee_text, :bare => true)
86
+ javascript_text << <<-JS
87
+
88
+ __udf__.parameters || (__udf__.parameters = []);
89
+ __udf__.returns || (__udf__.returns = "Scalar");
90
+ var __scalarTypes__ = {"Numeric":true,"String":true,"Boolean":true,"DateTime":true,"Decimal":true,"Scalar":true};
91
+ function __getType__(type) {
92
+ if (__scalarTypes__[type]) {
93
+ return new mondrian.olap.type[type+"Type"];
94
+ } else if (type === "Member") {
95
+ return mondrian.olap.type.MemberType.Unknown;
96
+ } else {
97
+ return null;
98
+ }
99
+ }
100
+ function getParameterTypes() {
101
+ var parameters = __udf__.parameters || [],
102
+ types = [];
103
+ for (var i = 0, len = parameters.length; i < len; i++) {
104
+ types.push(__getType__(parameters[i]))
105
+ }
106
+ return types;
107
+ }
108
+ function getReturnType(parameterTypes) {
109
+ var returns = __udf__.returns || "Scalar";
110
+ return __getType__(returns);
111
+ }
112
+ if (__udf__.syntax) {
113
+ function getSyntax() {
114
+ return mondrian.olap.Syntax[__udf__.syntax];
115
+ }
116
+ }
117
+ function execute(evaluator, args) {
118
+ var parameters = __udf__.parameters || [],
119
+ values = [],
120
+ value;
121
+ for (var i = 0, len = parameters.length; i < len; i++) {
122
+ if (__scalarTypes__[parameters[i]]) {
123
+ value = args[i].evaluateScalar(evaluator);
124
+ } else {
125
+ value = args[i].evaluate(evaluator);
126
+ }
127
+ values.push(value);
128
+ }
129
+ return __udf__.execute.apply(__udf__, values);
130
+ }
131
+ JS
132
+ javascript javascript_text
133
+ end
134
+
135
+ class RubyUdfBase
136
+ include Java::mondrian.spi.UserDefinedFunction
137
+ def self.function_name=(name); @function_name = name; end
138
+ def self.function_name; @function_name; end
139
+
140
+ def getName
141
+ self.class.function_name
142
+ end
143
+ add_method_signature("getName", [java.lang.String])
144
+
145
+ def getDescription
146
+ getName
147
+ end
148
+ add_method_signature("getDescription", [java.lang.String])
149
+
150
+ def self.parameters(*types)
151
+ if types.empty?
152
+ @parameters || []
153
+ else
154
+ @parameters = types.map{|type| stringified_type(type)}
155
+ end
156
+ end
157
+
158
+ def self.returns(type = nil)
159
+ if type
160
+ @returns = stringified_type(type)
161
+ else
162
+ @returns || 'Scalar'
163
+ end
164
+ end
165
+
166
+ VALID_SYNTAX_TYPES = %w(Function Property Method)
167
+ def self.syntax(type = nil)
168
+ if type
169
+ type = stringify(type)
170
+ raise ArgumentError, "invalid user defined function type #{type.inspect}" unless VALID_SYNTAX_TYPES.include? type
171
+ @syntax = type
172
+ else
173
+ @syntax || 'Function'
174
+ end
175
+ end
176
+
177
+ def getSyntax
178
+ Java::mondrian.olap.Syntax.const_get self.class.syntax
179
+ end
180
+ add_method_signature("getSyntax", [Java::mondrian.olap.Syntax])
181
+
182
+ UDF_SCALAR_TYPES = {
183
+ "Numeric" => Java::mondrian.olap.type.NumericType,
184
+ "String" => Java::mondrian.olap.type.StringType,
185
+ "Boolean" => Java::mondrian.olap.type.BooleanType,
186
+ "DateTime" => Java::mondrian.olap.type.DateTimeType,
187
+ "Decimal" => Java::mondrian.olap.type.DecimalType,
188
+ "Scalar" => Java::mondrian.olap.type.ScalarType
189
+ }
190
+ UDF_OTHER_TYPES = {
191
+ "Member" => Java::mondrian.olap.type.MemberType::Unknown,
192
+ "Set" => Java::mondrian.olap.type.SetType.new(Java::mondrian.olap.type.MemberType::Unknown),
193
+ "Hierarchy" => Java::mondrian.olap.type.HierarchyType.new(nil, nil),
194
+ "Level" => Java::mondrian.olap.type.LevelType::Unknown
195
+ }
196
+
197
+ def getParameterTypes
198
+ @parameterTypes ||= self.class.parameters.map{|p| get_java_type(p)}
199
+ end
200
+ class_loader = JRuby.runtime.jruby_class_loader
201
+ type_array_class = java.lang.Class.forName "[Lmondrian.olap.type.Type;", true, class_loader
202
+ add_method_signature("getParameterTypes", [type_array_class])
203
+
204
+ def getReturnType(parameterTypes)
205
+ @returnType ||= get_java_type self.class.returns
206
+ end
207
+ add_method_signature("getReturnType", [Java::mondrian.olap.type.Type, type_array_class])
208
+
209
+ def getReservedWords
210
+ nil
211
+ end
212
+ string_array_class = java.lang.Class.forName "[Ljava.lang.String;", true, class_loader
213
+ add_method_signature("getReservedWords", [string_array_class])
214
+
215
+ def execute(evaluator, arguments)
216
+ values = []
217
+ self.class.parameters.each_with_index do |p,i|
218
+ value = UDF_SCALAR_TYPES[p] ? arguments[i].evaluateScalar(evaluator) : arguments[i].evaluate(evaluator)
219
+ values << value
220
+ end
221
+ call_with_evaluator(evaluator, *values)
222
+ end
223
+ arguments_array_class = java.lang.Class.forName "[Lmondrian.spi.UserDefinedFunction$Argument;", true, class_loader
224
+ add_method_signature("execute", [java.lang.Object, Java::mondrian.olap.Evaluator, arguments_array_class])
225
+
226
+ # Override this metho if evaluator is needed
227
+ def call_with_evaluator(evaluator, *values)
228
+ call(*values)
229
+ end
230
+
231
+ private
232
+
233
+ def get_java_type(type)
234
+ if type_class = UDF_SCALAR_TYPES[type]
235
+ type_class.new
236
+ else
237
+ UDF_OTHER_TYPES[type]
238
+ end
239
+ end
240
+
241
+ def self.stringified_type(type)
242
+ type = stringify(type)
243
+ raise ArgumentError, "invalid user defined function type #{type.inspect}" unless UDF_SCALAR_TYPES[type] || UDF_OTHER_TYPES[type]
244
+ type
245
+ end
246
+
247
+ def self.stringify(arg)
248
+ arg = arg.to_s.split('_').map{|s| s.capitalize}.join if arg.is_a? Symbol
249
+ arg
250
+ end
251
+ end
252
+
253
+ def ruby(*options, &block)
254
+ udf_class_name = if options.include?(:shared)
255
+ "#{name.capitalize}Udf"
256
+ end
257
+ if udf_class_name && self.class.const_defined?(udf_class_name)
258
+ udf_class = self.class.const_get(udf_class_name)
259
+ else
260
+ udf_class = Class.new(RubyUdfBase)
261
+ self.class.const_set(udf_class_name, udf_class) if udf_class_name
262
+ end
263
+ udf_class.function_name = name
264
+ udf_class.class_eval(&block)
265
+ udf_java_class = udf_class.become_java!(false)
266
+
267
+ class_name udf_java_class.getName
268
+ end
269
+ end
270
+
271
+ class Script < SchemaElement
272
+ attributes :language
273
+ content :text
274
+ end
275
+
276
+ class CellFormatter < SchemaElement
277
+ include ScriptElements
278
+ # Name of a formatter class for the appropriate cell being displayed.
279
+ # The class must implement the mondrian.olap.CellFormatter interface.
280
+ attributes :class_name
281
+ elements :script
282
+
283
+ def initialize(name = nil, attributes = {}, parent = nil, &block)
284
+ super
285
+ if name && !attributes[:class_name] && !block_given?
286
+ # use shared ruby implementation
287
+ @attributes[:class_name] = ruby_formatter_java_class_name(name)
288
+ @attributes.delete(:name)
289
+ end
290
+ end
291
+
292
+ def coffeescript(text)
293
+ coffeescript_function('(value)', text)
294
+ end
295
+
296
+ def ruby(*options, &block)
297
+ ruby_formatter(options, Java::mondrian.spi.CellFormatter, 'formatCell', [java.lang.String, java.lang.Object], &block)
298
+ end
299
+ end
300
+
301
+ class MemberFormatter < SchemaElement
302
+ include ScriptElements
303
+ attributes :class_name
304
+ elements :script
305
+
306
+ def coffeescript(text)
307
+ coffeescript_function('(member)', text)
308
+ end
309
+
310
+ def ruby(*options, &block)
311
+ ruby_formatter(options, Java::mondrian.spi.MemberFormatter, 'formatMember', [java.lang.String, Java::mondrian.olap.Member], &block)
312
+ end
313
+ end
314
+
315
+ class PropertyFormatter < SchemaElement
316
+ include ScriptElements
317
+ attributes :class_name
318
+ elements :script
319
+
320
+ def coffeescript(text)
321
+ coffeescript_function('(member,propertyName,propertyValue)', text)
322
+ end
323
+
324
+ def ruby(*options, &block)
325
+ ruby_formatter(options, Java::mondrian.spi.PropertyFormatter, 'formatProperty', [java.lang.String, Java::mondrian.olap.Member, java.lang.String, java.lang.Object], &block)
326
+ end
327
+ end
328
+
329
+ end
330
+ end
331
+ end
@@ -0,0 +1,5 @@
1
+ module Mondrian
2
+ module OLAP
3
+ VERSION = File.read(File.expand_path('../../../../VERSION', __FILE__)).chomp
4
+ end
5
+ end
@@ -0,0 +1,130 @@
1
+ require "spec_helper"
2
+
3
+ describe "Connection role" do
4
+
5
+ describe "create connection" do
6
+ before(:each) do
7
+ @role_name = role_name = 'California manager'
8
+ @role_name2 = role_name2 = 'Dummy, with comma'
9
+ @schema = Mondrian::OLAP::Schema.define do
10
+ cube 'Sales' do
11
+ table 'sales'
12
+ dimension 'Gender', :foreign_key => 'customer_id' do
13
+ hierarchy :has_all => true, :primary_key => 'id' do
14
+ table 'customers'
15
+ level 'Gender', :column => 'gender', :unique_members => true
16
+ end
17
+ end
18
+ dimension 'Customers', :foreign_key => 'customer_id' do
19
+ hierarchy :has_all => true, :all_member_name => 'All Customers', :primary_key => 'id' do
20
+ table 'customers'
21
+ level 'Country', :column => 'country', :unique_members => true
22
+ level 'State Province', :column => 'state_province', :unique_members => true
23
+ level 'City', :column => 'city', :unique_members => false
24
+ level 'Name', :column => 'fullname', :unique_members => true
25
+ end
26
+ end
27
+ dimension 'Time', :foreign_key => 'time_id' do
28
+ hierarchy :has_all => false, :primary_key => 'id' do
29
+ table 'time'
30
+ level 'Year', :column => 'the_year', :type => 'Numeric', :unique_members => true
31
+ level 'Quarter', :column => 'quarter', :unique_members => false
32
+ level 'Month', :column => 'month_of_year', :type => 'Numeric', :unique_members => false
33
+ end
34
+ end
35
+ measure 'Unit Sales', :column => 'unit_sales', :aggregator => 'sum'
36
+ measure 'Store Sales', :column => 'store_sales', :aggregator => 'sum'
37
+ end
38
+ role role_name do
39
+ schema_grant :access => 'none' do
40
+ cube_grant :cube => 'Sales', :access => 'all' do
41
+ dimension_grant :dimension => '[Measures]', :access => 'all'
42
+ hierarchy_grant :hierarchy => '[Customers]', :access => 'custom',
43
+ :top_level => '[Customers].[State Province]', :bottom_level => '[Customers].[City]' do
44
+ member_grant :member => '[Customers].[USA].[CA]', :access => 'all'
45
+ member_grant :member => '[Customers].[USA].[CA].[Los Angeles]', :access => 'none'
46
+ end
47
+ end
48
+ end
49
+ end
50
+ role role_name2
51
+
52
+ # to test that Role elements are generated before UserDefinedFunction
53
+ user_defined_function 'Factorial' do
54
+ ruby do
55
+ parameters :numeric
56
+ returns :numeric
57
+ def call(n)
58
+ n <= 1 ? 1 : n * call(n - 1)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ @olap = Mondrian::OLAP::Connection.create(CONNECTION_PARAMS.merge :schema => @schema)
64
+ end
65
+
66
+ it "should connect" do
67
+ @olap.should be_connected
68
+ end
69
+
70
+ it "should get available role names" do
71
+ @olap.available_role_names.should == [@role_name, @role_name2]
72
+ end
73
+
74
+ it "should not get role name if not set" do
75
+ @olap.role_name.should be_nil
76
+ @olap.role_names.should be_empty
77
+ end
78
+
79
+ it "should set and get role name" do
80
+ @olap.role_name = @role_name
81
+ @olap.role_name.should == @role_name
82
+ @olap.role_names.should == [@role_name]
83
+ end
84
+
85
+ it "should raise error when invalid role name is set" do
86
+ expect {
87
+ @olap.role_name = 'invalid'
88
+ }.to raise_error {|e|
89
+ e.should be_kind_of(Mondrian::OLAP::Error)
90
+ e.message.should == "org.olap4j.OlapException: Unknown role 'invalid'"
91
+ e.root_cause_message.should == "Unknown role 'invalid'"
92
+ }
93
+ end
94
+
95
+ it "should set and get several role names" do
96
+ @olap.role_names = [@role_name, @role_name2]
97
+ @olap.role_name.should == "[#{@role_name}, #{@role_name2}]"
98
+ @olap.role_names.should == [@role_name, @role_name2]
99
+ end
100
+
101
+ it "should not get non-visible member" do
102
+ @cube = @olap.cube('Sales')
103
+ @cube.member('[Customers].[USA].[CA].[Los Angeles]').should_not be_nil
104
+ @olap.role_name = @role_name
105
+ @cube.member('[Customers].[USA].[CA].[Los Angeles]').should be_nil
106
+ end
107
+
108
+ # TODO: investigate why role name is not returned when set in connection string
109
+ # it "should set role name from connection parameters" do
110
+ # @olap = Mondrian::OLAP::Connection.create(CONNECTION_PARAMS.merge :schema => @schema,
111
+ # :role => @role_name)
112
+ # @olap.role_name.should == @role_name
113
+ # end
114
+
115
+ it "should not get non-visible member when role name set in connection parameters" do
116
+ @olap = Mondrian::OLAP::Connection.create(CONNECTION_PARAMS.merge :schema => @schema,
117
+ :role => @role_name)
118
+ @cube = @olap.cube('Sales')
119
+ @cube.member('[Customers].[USA].[CA].[Los Angeles]').should be_nil
120
+ end
121
+
122
+ it "should not get non-visible member when several role names set in connection parameters" do
123
+ @olap = Mondrian::OLAP::Connection.create(CONNECTION_PARAMS.merge :schema => @schema,
124
+ :roles => [@role_name, @role_name2])
125
+ @cube = @olap.cube('Sales')
126
+ @cube.member('[Customers].[USA].[CA].[Los Angeles]').should be_nil
127
+ end
128
+
129
+ end
130
+ end