mondrian-olap 0.8.0 → 1.1.0
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.
- checksums.yaml +5 -5
- data/Changelog.md +36 -0
- data/LICENSE.txt +1 -1
- data/README.md +5 -2
- data/VERSION +1 -1
- data/lib/mondrian/jars/commons-collections-3.2.2.jar +0 -0
- data/lib/mondrian/jars/commons-lang-2.6.jar +0 -0
- data/lib/mondrian/jars/commons-logging-1.2.jar +0 -0
- data/lib/mondrian/jars/commons-vfs2-2.2.jar +0 -0
- data/lib/mondrian/jars/eigenbase-xom-1.3.5.jar +0 -0
- data/lib/mondrian/jars/log4j.properties +2 -4
- data/lib/mondrian/jars/mondrian-8.3.0.5.jar +0 -0
- data/lib/mondrian/olap/connection.rb +112 -16
- data/lib/mondrian/olap/cube.rb +9 -2
- data/lib/mondrian/olap/error.rb +37 -8
- data/lib/mondrian/olap/query.rb +14 -17
- data/lib/mondrian/olap/result.rb +73 -40
- data/lib/mondrian/olap/schema.rb +1 -0
- data/lib/mondrian/olap/schema_element.rb +20 -4
- data/lib/mondrian/olap/schema_udf.rb +21 -16
- data/spec/connection_role_spec.rb +65 -12
- data/spec/connection_spec.rb +2 -0
- data/spec/cube_cache_control_spec.rb +16 -12
- data/spec/query_spec.rb +157 -21
- data/spec/schema_definition_spec.rb +151 -55
- data/spec/spec_helper.rb +75 -0
- metadata +65 -64
- data/lib/mondrian/jars/commons-collections-3.2.1.jar +0 -0
- data/lib/mondrian/jars/commons-logging-1.1.1.jar +0 -0
- data/lib/mondrian/jars/commons-vfs2-2.1-20150824.jar +0 -0
- data/lib/mondrian/jars/eigenbase-xom-1.3.1.jar +0 -0
- data/lib/mondrian/jars/mondrian-3.12.0.6-237.jar +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0df66cbf2bfa1f2a0a746568e7491398870121101d15b23d486e270877de3900
|
4
|
+
data.tar.gz: bfd14249c31c8f4b050c186cf5b355aaa6d91a8a042b89555d862868cfa52ee8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 62219364cd64926f57429c4e6ff3373bc5fc19eaadd638544875407357ed11c5442716a6f5245078980762f31c170813bc8ed86e0c7dee6a54c1063c97827b03
|
7
|
+
data.tar.gz: c48f2a34b98c53955af10ccf093bcb73797e6f122282d70ffdf4a0cfeecded72a413bdf782ad68a58c9b44733bd9d4129bf865551fab894b98e1dcafeec717d8
|
data/Changelog.md
CHANGED
@@ -1,3 +1,39 @@
|
|
1
|
+
### 1.1.0 / 2019-11-09
|
2
|
+
|
3
|
+
* New features
|
4
|
+
* Upgrade to the latest Mondrian version 8.3.0.5
|
5
|
+
* Tested with JRuby 9.2.9.0
|
6
|
+
* Set query specific timeout
|
7
|
+
* Support for Vertica and Snowflake databases
|
8
|
+
* Bug fixes
|
9
|
+
* Handle and wrap TokenMgrError exception
|
10
|
+
* Patch for MONDRIAN-2660
|
11
|
+
* Patch for MONDRIAN-2661
|
12
|
+
|
13
|
+
### 1.0.0 / 2019-03-04
|
14
|
+
|
15
|
+
* New features
|
16
|
+
* Upgrade to the latest Mondrian version 8.2.0.4
|
17
|
+
* Desupport Java 7, added support for Java 11, tested with JRuby 9.2.6.0
|
18
|
+
* Remove deprecated NativeException, Fixnum
|
19
|
+
* Added Mondrian query profiling option
|
20
|
+
* Added connection flush_schema method and flush_schema(schema_key) class method
|
21
|
+
* Added pin_schema_timeout connection parameter
|
22
|
+
* Bug fixes
|
23
|
+
* Fixed parsing of drill through queries with newlines
|
24
|
+
* Do not log Mondrian errors on the console
|
25
|
+
* Fixed handling of dimension names with escaped ]
|
26
|
+
* Patch for MONDRIAN-2641
|
27
|
+
|
28
|
+
### 0.9.0 / 2017-10-07
|
29
|
+
|
30
|
+
* New features
|
31
|
+
* Upgraded to the latest Mondrian version 3.14.0.5
|
32
|
+
* Added an annotations_hash method for schema elements
|
33
|
+
* Bug fixes
|
34
|
+
* Fixed drill through SQL query generation
|
35
|
+
* Set a single role as a union role - used as a workaround for a Mondrian bug
|
36
|
+
|
1
37
|
### 0.8.0 / 2016-10-26
|
2
38
|
|
3
39
|
* New features
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
[](https://travis-ci.org/rsim/mondrian-olap)
|
2
|
+
[](https://ci.appveyor.com/project/rsim/mondrian-olap)
|
3
|
+
|
1
4
|
mondrian-olap
|
2
5
|
=============
|
3
6
|
|
@@ -270,9 +273,9 @@ See more examples of data access roles in `spec/connection_role_spec.rb`.
|
|
270
273
|
REQUIREMENTS
|
271
274
|
------------
|
272
275
|
|
273
|
-
mondrian-olap gem is compatible with JRuby versions 1.7 and 9.
|
276
|
+
mondrian-olap gem is compatible with JRuby versions 1.7 and 9.x, and Java 8 and 11 VM. mondrian-olap works only with JRuby and not with other Ruby implementations as it includes Mondrian OLAP Java libraries.
|
274
277
|
|
275
|
-
mondrian-olap supports MySQL, PostgreSQL, Oracle, LucidDB and Microsoft SQL Server databases as well as other databases that are supported by Mondrian OLAP engine (using jdbc_driver and jdbc_url connection parameters). When using MySQL, PostgreSQL or LucidDB databases then install jdbc-mysql, jdbc-postgres or jdbc-luciddb gem and require "jdbc/mysql", "jdbc/postgres" or "jdbc/luciddb" to load the corresponding JDBC database driver. When using Oracle then include Oracle JDBC driver (`
|
278
|
+
mondrian-olap supports MySQL, PostgreSQL, Oracle, LucidDB and Microsoft SQL Server databases as well as other databases that are supported by Mondrian OLAP engine (using jdbc_driver and jdbc_url connection parameters). When using MySQL, PostgreSQL or LucidDB databases then install jdbc-mysql, jdbc-postgres or jdbc-luciddb gem and require "jdbc/mysql", "jdbc/postgres" or "jdbc/luciddb" to load the corresponding JDBC database driver. When using Oracle then include Oracle JDBC driver (`ojdbc8.jar` for Java 8) in `CLASSPATH` or copy to `JRUBY_HOME/lib` or require it in application manually. When using SQL Server you can choose between the jTDS or Microsoft JDBC drivers. If you use jTDS require "jdbc/jtds". If you use the Microsoft JDBC driver then include the latest `mssql-jdbc-*.jar` in `CLASSPATH` or copy to `JRUBY_HOME/lib` or require it in application manually.
|
276
279
|
|
277
280
|
INSTALL
|
278
281
|
-------
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
1.1.0
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -7,10 +7,10 @@ module Mondrian
|
|
7
7
|
connection
|
8
8
|
end
|
9
9
|
|
10
|
-
attr_reader :raw_connection, :raw_catalog, :raw_schema,
|
10
|
+
attr_reader :raw_connection, :raw_mondrian_connection, :raw_catalog, :raw_schema,
|
11
11
|
:raw_schema_reader, :raw_cache_control
|
12
12
|
|
13
|
-
def initialize(params={})
|
13
|
+
def initialize(params = {})
|
14
14
|
@params = params
|
15
15
|
@driver = params[:driver]
|
16
16
|
@connected = false
|
@@ -55,8 +55,9 @@ module Mondrian
|
|
55
55
|
@raw_catalog = @raw_connection.getOlapCatalog
|
56
56
|
# currently it is assumed that there is just one schema per connection catalog
|
57
57
|
@raw_schema = @raw_catalog.getSchemas.first
|
58
|
-
@
|
59
|
-
@
|
58
|
+
@raw_mondrian_connection = @raw_connection.getMondrianConnection
|
59
|
+
@raw_schema_reader = @raw_mondrian_connection.getSchemaReader
|
60
|
+
@raw_cache_control = @raw_mondrian_connection.getCacheControl(nil)
|
60
61
|
@connected = true
|
61
62
|
true
|
62
63
|
end
|
@@ -67,17 +68,24 @@ module Mondrian
|
|
67
68
|
end
|
68
69
|
|
69
70
|
def close
|
71
|
+
@raw_jdbc_connection = @raw_catalog = @raw_schema = @raw_mondrian_connection = nil
|
72
|
+
@raw_schema_reader = @raw_cache_control = nil
|
70
73
|
@raw_connection.close
|
74
|
+
@raw_connection = nil
|
71
75
|
@connected = false
|
72
|
-
@raw_connection = @raw_jdbc_connection = nil
|
73
76
|
true
|
74
77
|
end
|
75
78
|
|
76
79
|
def execute(query_string, parameters = {})
|
77
|
-
|
80
|
+
options = {}
|
81
|
+
Error.wrap_native_exception(options) do
|
82
|
+
start_time = Time.now
|
78
83
|
statement = @raw_connection.prepareOlapStatement(query_string)
|
84
|
+
options[:profiling_statement] = statement if parameters[:profiling]
|
79
85
|
set_statement_parameters(statement, parameters)
|
80
|
-
|
86
|
+
raw_cell_set = statement.executeQuery()
|
87
|
+
total_duration = ((Time.now - start_time) * 1000).to_i
|
88
|
+
Result.new(self, raw_cell_set, profiling_handler: statement.getProfileHandler, total_duration: total_duration)
|
81
89
|
end
|
82
90
|
end
|
83
91
|
|
@@ -99,6 +107,36 @@ module Mondrian
|
|
99
107
|
Query.from(self, cube_name)
|
100
108
|
end
|
101
109
|
|
110
|
+
def raw_schema_key
|
111
|
+
@raw_mondrian_connection.getSchema.getKey
|
112
|
+
end
|
113
|
+
|
114
|
+
def schema_key
|
115
|
+
raw_schema_key.toString
|
116
|
+
end
|
117
|
+
|
118
|
+
def self.raw_schema_key(schema_key)
|
119
|
+
if schema_key =~ /\A<(.*), (.*)>\z/
|
120
|
+
schema_content_key = $1
|
121
|
+
connection_key = $2
|
122
|
+
|
123
|
+
cons = Java::mondrian.rolap.SchemaContentKey.java_class.declared_constructor(java.lang.String)
|
124
|
+
cons.accessible = true
|
125
|
+
raw_schema_content_key = cons.new_instance(schema_content_key)
|
126
|
+
|
127
|
+
cons = Java::mondrian.rolap.ConnectionKey.java_class.declared_constructor(java.lang.String)
|
128
|
+
cons.accessible = true
|
129
|
+
raw_connection_key = cons.new_instance(connection_key)
|
130
|
+
|
131
|
+
cons = Java::mondrian.rolap.SchemaKey.java_class.declared_constructor(
|
132
|
+
Java::mondrian.rolap.SchemaContentKey, Java::mondrian.rolap.ConnectionKey)
|
133
|
+
cons.accessible = true
|
134
|
+
cons.new_instance(raw_schema_content_key, raw_connection_key)
|
135
|
+
else
|
136
|
+
raise ArgumentError, "invalid schema key #{schema_key}"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
102
140
|
def cube_names
|
103
141
|
@raw_schema.getCubes.map{|c| c.getName}
|
104
142
|
end
|
@@ -109,12 +147,37 @@ module Mondrian
|
|
109
147
|
|
110
148
|
# Will affect only the next created connection. If it is necessary to clear all schema cache then
|
111
149
|
# flush_schema_cache should be called, then close and then new connection should be created.
|
150
|
+
# This method flushes schemas for all connections (clears the schema pool).
|
112
151
|
def flush_schema_cache
|
113
|
-
unwrapped_connection = @raw_connection.unwrap(Java::MondrianOlap::Connection.java_class)
|
114
|
-
raw_cache_control = unwrapped_connection.getCacheControl(nil)
|
115
152
|
raw_cache_control.flushSchemaCache
|
116
153
|
end
|
117
154
|
|
155
|
+
def self.raw_schema_pool
|
156
|
+
method = Java::mondrian.rolap.RolapSchemaPool.java_class.declared_method('instance')
|
157
|
+
method.accessible = true
|
158
|
+
method.invoke_static
|
159
|
+
end
|
160
|
+
|
161
|
+
def self.flush_schema_cache
|
162
|
+
method = Java::mondrian.rolap.RolapSchemaPool.java_class.declared_method('clear')
|
163
|
+
method.accessible = true
|
164
|
+
method.invoke(raw_schema_pool)
|
165
|
+
end
|
166
|
+
|
167
|
+
# This method flushes the schema only for this connection (removes from the schema pool).
|
168
|
+
def flush_schema
|
169
|
+
if raw_mondrian_connection && (rolap_schema = raw_mondrian_connection.getSchema)
|
170
|
+
raw_cache_control.flushSchema(rolap_schema)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def self.flush_schema(schema_key)
|
175
|
+
method = Java::mondrian.rolap.RolapSchemaPool.java_class.declared_method('remove',
|
176
|
+
Java::mondrian.rolap.SchemaKey.java_class)
|
177
|
+
method.accessible = true
|
178
|
+
method.invoke(raw_schema_pool, raw_schema_key(schema_key))
|
179
|
+
end
|
180
|
+
|
118
181
|
def available_role_names
|
119
182
|
@raw_connection.getAvailableRoleNames.to_a
|
120
183
|
end
|
@@ -139,7 +202,9 @@ module Mondrian
|
|
139
202
|
Error.wrap_native_exception do
|
140
203
|
# workaround to access non-public method (was not public when using inside Torquebox)
|
141
204
|
# @raw_connection.setRoleNames(Array(names))
|
142
|
-
|
205
|
+
names = Array(names)
|
206
|
+
@raw_connection.java_method(:setRoleNames, [Java::JavaUtil::List.java_class]).call(names)
|
207
|
+
names
|
143
208
|
end
|
144
209
|
end
|
145
210
|
|
@@ -149,7 +214,7 @@ module Mondrian
|
|
149
214
|
|
150
215
|
def locale=(locale)
|
151
216
|
locale_elements = locale.to_s.split('_')
|
152
|
-
raise ArgumentError, "invalid locale string #{locale.inspect}" unless [1,2,3].include?(locale_elements.length)
|
217
|
+
raise ArgumentError, "invalid locale string #{locale.inspect}" unless [1, 2, 3].include?(locale_elements.length)
|
153
218
|
java_locale = Java::JavaUtil::Locale.new(*locale_elements)
|
154
219
|
@raw_connection.setLocale(java_locale)
|
155
220
|
end
|
@@ -230,6 +295,7 @@ module Mondrian
|
|
230
295
|
string = "jdbc:mondrian:Jdbc=#{quote_string(jdbc_uri)};JdbcDrivers=#{jdbc_driver};"
|
231
296
|
# by default use content checksum to reload schema when catalog has changed
|
232
297
|
string << "UseContentChecksum=true;" unless @params[:use_content_checksum] == false
|
298
|
+
string << "PinSchemaTimeout=#{@params[:pin_schema_timeout]};" if @params[:pin_schema_timeout]
|
233
299
|
if role = @params[:role] || @params[:roles]
|
234
300
|
roles = Array(role).map{|r| r && r.to_s.gsub(',', ',,')}.compact
|
235
301
|
string << "Role=#{quote_string(roles.join(','))};" unless roles.empty?
|
@@ -242,7 +308,7 @@ module Mondrian
|
|
242
308
|
|
243
309
|
def jdbc_uri
|
244
310
|
case @driver
|
245
|
-
when 'mysql', 'postgresql'
|
311
|
+
when 'mysql', 'postgresql', 'vertica'
|
246
312
|
uri = "jdbc:#{@driver}://#{@params[:host]}#{@params[:port] && ":#{@params[:port]}"}/#{@params[:database]}"
|
247
313
|
uri << "?useUnicode=yes&characterEncoding=UTF-8" if @driver == 'mysql'
|
248
314
|
if (properties = @params[:properties]).is_a?(Hash) && !properties.empty?
|
@@ -281,6 +347,15 @@ module Mondrian
|
|
281
347
|
uri << ";applicationName=#{@params[:application_name]}" if @params[:application_name]
|
282
348
|
uri << ";instanceName=#{@params[:instance_name]}" if @params[:instance_name]
|
283
349
|
uri
|
350
|
+
when 'snowflake'
|
351
|
+
uri = "jdbc:snowflake://#{@params[:host]}#{@params[:port] && ":#{@params[:port]}"}/?db=#{@params[:database]}"
|
352
|
+
uri << "&schema=#{@params[:database_schema]}" if @params[:database_schema]
|
353
|
+
uri << "&warehouse=#{@params[:warehouse]}" if @params[:warehouse]
|
354
|
+
if (properties = @params[:properties]).is_a?(Hash) && !properties.empty?
|
355
|
+
uri << '&'
|
356
|
+
uri << properties.map{|k, v| "#{k}=#{v}"}.join('&')
|
357
|
+
end
|
358
|
+
uri
|
284
359
|
when 'jdbc'
|
285
360
|
@params[:jdbc_url] or raise ArgumentError, 'missing jdbc_url parameter'
|
286
361
|
else
|
@@ -302,6 +377,10 @@ module Mondrian
|
|
302
377
|
'net.sourceforge.jtds.jdbc.Driver'
|
303
378
|
when 'sqlserver'
|
304
379
|
'com.microsoft.sqlserver.jdbc.SQLServerDriver'
|
380
|
+
when 'vertica'
|
381
|
+
'com.vertica.jdbc.Driver'
|
382
|
+
when 'snowflake'
|
383
|
+
'net.snowflake.client.jdbc.SnowflakeDriver'
|
305
384
|
when 'jdbc'
|
306
385
|
@params[:jdbc_driver] or raise ArgumentError, 'missing jdbc_driver parameter'
|
307
386
|
else
|
@@ -328,15 +407,14 @@ module Mondrian
|
|
328
407
|
end
|
329
408
|
|
330
409
|
def quote_string(string)
|
331
|
-
"'#{string.gsub("'","''")}'"
|
410
|
+
"'#{string.gsub("'", "''")}'"
|
332
411
|
end
|
333
412
|
|
334
413
|
def set_statement_parameters(statement, parameters)
|
335
414
|
if parameters && !parameters.empty?
|
415
|
+
parameters = parameters.dup
|
336
416
|
# define addtional parameters which can be accessed from user defined functions
|
337
|
-
if parameters
|
338
|
-
parameters = parameters.dup
|
339
|
-
define_parameters = parameters.delete(:define_parameters)
|
417
|
+
if define_parameters = parameters.delete(:define_parameters)
|
340
418
|
query_validator = statement.getQuery.createValidator
|
341
419
|
define_parameters.each do |dp_name, dp_value|
|
342
420
|
dp_type_class = dp_value.is_a?(Numeric) ? Java::MondrianOlapType::NumericType : Java::MondrianOlapType::StringType
|
@@ -344,12 +422,30 @@ module Mondrian
|
|
344
422
|
parameters[dp_name] = dp_value
|
345
423
|
end
|
346
424
|
end
|
425
|
+
if parameters.delete(:profiling)
|
426
|
+
statement.enableProfiling(ProfilingHandler.new)
|
427
|
+
end
|
428
|
+
if timeout = parameters.delete(:timeout)
|
429
|
+
statement.getQuery.setQueryTimeoutMillis(timeout * 1000)
|
430
|
+
end
|
347
431
|
parameters.each do |parameter_name, value|
|
348
432
|
statement.getQuery.setParameter(parameter_name, value)
|
349
433
|
end
|
350
434
|
end
|
351
435
|
end
|
352
436
|
|
437
|
+
class ProfilingHandler
|
438
|
+
java_implements Java::mondrian.spi.ProfileHandler
|
439
|
+
attr_reader :plan
|
440
|
+
attr_reader :timing
|
441
|
+
|
442
|
+
java_signature 'void explain(String plan, mondrian.olap.QueryTiming timing)'
|
443
|
+
def explain(plan, timing)
|
444
|
+
@plan = plan
|
445
|
+
@timing = timing
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
353
449
|
end
|
354
450
|
end
|
355
451
|
end
|
data/lib/mondrian/olap/cube.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
1
3
|
module Mondrian
|
2
4
|
module OLAP
|
3
5
|
module Annotated
|
@@ -400,13 +402,18 @@ module Mondrian
|
|
400
402
|
end
|
401
403
|
|
402
404
|
def cell_formatter_name
|
405
|
+
if cf = cell_formatter
|
406
|
+
cf.class.name.split('::').last.gsub(/Udf\z/, '')
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
410
|
+
def cell_formatter
|
403
411
|
if dimension_type == :measures
|
404
412
|
cube_measure = raw_member.unwrap(Java::MondrianOlap::Member.java_class)
|
405
413
|
if value_formatter = cube_measure.getFormatter
|
406
414
|
f = value_formatter.java_class.declared_field('cf')
|
407
415
|
f.accessible = true
|
408
|
-
|
409
|
-
cf.class.name.split('::').last.gsub(/Udf\z/, '')
|
416
|
+
f.value(value_formatter)
|
410
417
|
end
|
411
418
|
end
|
412
419
|
end
|
data/lib/mondrian/olap/error.rb
CHANGED
@@ -6,25 +6,43 @@ module Mondrian
|
|
6
6
|
class Error < StandardError
|
7
7
|
# root_cause will be nil if there is no cause for wrapped native error
|
8
8
|
# root_cause_message will have either root_cause message or wrapped native error message
|
9
|
-
attr_reader :native_error, :root_cause_message, :root_cause
|
9
|
+
attr_reader :native_error, :root_cause_message, :root_cause, :profiling_handler
|
10
10
|
|
11
|
-
def initialize(native_error)
|
11
|
+
def initialize(native_error, options = {})
|
12
12
|
@native_error = native_error
|
13
13
|
get_root_cause
|
14
|
-
super(native_error.
|
14
|
+
super(native_error.toString)
|
15
15
|
add_root_cause_to_backtrace
|
16
|
+
get_profiling(options)
|
16
17
|
end
|
17
18
|
|
18
|
-
def self.wrap_native_exception
|
19
|
+
def self.wrap_native_exception(options = {})
|
19
20
|
yield
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
# TokenMgrError for some unknown reason extends java.lang.Error which normally should not be rescued
|
22
|
+
rescue Java::JavaLang::Exception, Java::MondrianParser::TokenMgrError => e
|
23
|
+
if e.toString =~ NATIVE_ERROR_REGEXP
|
24
|
+
raise Mondrian::OLAP::Error.new(e, options)
|
23
25
|
else
|
24
26
|
raise
|
25
27
|
end
|
26
28
|
end
|
27
29
|
|
30
|
+
def profiling_plan
|
31
|
+
if profiling_handler && (plan = profiling_handler.plan)
|
32
|
+
plan.gsub("\r\n", "\n")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def profiling_timing
|
37
|
+
profiling_handler.timing if profiling_handler
|
38
|
+
end
|
39
|
+
|
40
|
+
def profiling_timing_string
|
41
|
+
if profiling_timing && (timing_string = profiling_timing.toString)
|
42
|
+
timing_string.gsub("\r\n", "\n")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
28
46
|
private
|
29
47
|
|
30
48
|
def get_root_cause
|
@@ -44,7 +62,7 @@ module Mondrian
|
|
44
62
|
bt = @native_error.backtrace
|
45
63
|
if @root_cause
|
46
64
|
root_cause_bt = Array(@root_cause.backtrace)
|
47
|
-
root_cause_bt[0,10].reverse.each do |bt_line|
|
65
|
+
root_cause_bt[0, 10].reverse.each do |bt_line|
|
48
66
|
bt.unshift "root cause: #{bt_line}"
|
49
67
|
end
|
50
68
|
bt.unshift "root cause: #{@root_cause.java_class.name}: #{@root_cause.message.chomp}"
|
@@ -52,6 +70,17 @@ module Mondrian
|
|
52
70
|
set_backtrace bt
|
53
71
|
end
|
54
72
|
|
73
|
+
def get_profiling(options)
|
74
|
+
if statement = options[:profiling_statement]
|
75
|
+
f = Java::mondrian.olap4j.MondrianOlap4jStatement.java_class.declared_field("openCellSet")
|
76
|
+
f.accessible = true
|
77
|
+
if cell_set = f.value(statement)
|
78
|
+
cell_set.close
|
79
|
+
@profiling_handler = statement.getProfileHandler
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
55
84
|
end
|
56
85
|
end
|
57
86
|
end
|