mondrian-olap 0.8.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Travis CI status](https://travis-ci.org/rsim/mondrian-olap.svg?branch=master)](https://travis-ci.org/rsim/mondrian-olap)
|
2
|
+
[![AppVeyor status](https://ci.appveyor.com/api/projects/status/08xd4tyty2k3wxba/branch/master?svg=true)](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
|