mondrian-olap 1.1.0 → 1.3.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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +33 -0
  3. data/LICENSE-Mondrian.txt +87 -0
  4. data/LICENSE.txt +1 -1
  5. data/README.md +4 -4
  6. data/VERSION +1 -1
  7. data/lib/mondrian/jars/guava-17.0.jar +0 -0
  8. data/lib/mondrian/jars/log4j-api-2.17.1.jar +0 -0
  9. data/lib/mondrian/jars/log4j-core-2.17.1.jar +0 -0
  10. data/lib/mondrian/jars/log4j2-config.jar +0 -0
  11. data/lib/mondrian/jars/mondrian-9.3.0.0.jar +0 -0
  12. data/lib/mondrian/olap/connection.rb +126 -73
  13. data/lib/mondrian/olap/cube.rb +46 -4
  14. data/lib/mondrian/olap/error.rb +10 -2
  15. data/lib/mondrian/olap/query.rb +1 -0
  16. data/lib/mondrian/olap/result.rb +132 -56
  17. data/lib/mondrian/olap/schema.rb +9 -3
  18. data/lib/mondrian/olap/schema_element.rb +6 -3
  19. data/lib/mondrian/olap/schema_udf.rb +8 -82
  20. data/lib/mondrian/olap.rb +11 -7
  21. data/spec/connection_role_spec.rb +4 -1
  22. data/spec/connection_spec.rb +38 -5
  23. data/spec/cube_cache_control_spec.rb +7 -17
  24. data/spec/cube_spec.rb +36 -2
  25. data/spec/fixtures/MondrianTest.xml +40 -6
  26. data/spec/fixtures/MondrianTestOracle.xml +40 -6
  27. data/spec/mondrian_spec.rb +203 -1
  28. data/spec/query_spec.rb +94 -25
  29. data/spec/rake_tasks.rb +319 -165
  30. data/spec/schema_definition_spec.rb +8 -241
  31. data/spec/spec_helper.rb +330 -112
  32. data/spec/support/data/customers.csv +10902 -0
  33. data/spec/support/data/product_classes.csv +101 -0
  34. data/spec/support/data/products.csv +101 -0
  35. data/spec/support/data/promotions.csv +11 -0
  36. data/spec/support/data/sales.csv +101 -0
  37. data/spec/support/data/time.csv +731 -0
  38. data/spec/support/data/warehouse.csv +101 -0
  39. data/spec/support/matchers/be_like.rb +1 -0
  40. metadata +42 -83
  41. data/LICENSE-Mondrian.html +0 -259
  42. data/lib/mondrian/jars/log4j-1.2.17.jar +0 -0
  43. data/lib/mondrian/jars/log4j.properties +0 -3
  44. data/lib/mondrian/jars/mondrian-8.3.0.5.jar +0 -0
data/spec/spec_helper.rb CHANGED
@@ -2,55 +2,148 @@ require 'rdoc'
2
2
  require 'rspec'
3
3
  require 'active_record'
4
4
  require 'activerecord-jdbc-adapter'
5
- require 'coffee-script'
6
- require 'rhino'
7
5
  require 'pry'
8
6
 
9
- # autoload corresponding JDBC driver during require 'jdbc/...'
7
+ # Autoload corresponding JDBC driver during require 'jdbc/...'
10
8
  Java::JavaLang::System.setProperty("jdbc.driver.autoload", "true")
11
9
 
12
10
  MONDRIAN_DRIVER = ENV['MONDRIAN_DRIVER'] || 'mysql'
13
11
  env_prefix = MONDRIAN_DRIVER.upcase
14
12
 
15
13
  DATABASE_HOST = ENV["#{env_prefix}_DATABASE_HOST"] || ENV['DATABASE_HOST'] || 'localhost'
14
+ DATABASE_PORT = ENV["#{env_prefix}_DATABASE_PORT"] || ENV['DATABASE_PORT']
15
+ DATABASE_PROTOCOL = ENV["#{env_prefix}_DATABASE_PROTOCOL"] || ENV['DATABASE_PROTOCOL']
16
16
  DATABASE_USER = ENV["#{env_prefix}_DATABASE_USER"] || ENV['DATABASE_USER'] || 'mondrian_test'
17
- DATABASE_PASSWORD = ENV["#{env_prefix}_DATABASE_PASSOWRD"] || ENV['DATABASE_PASSWORD'] || 'mondrian_test'
17
+ DATABASE_PASSWORD = ENV["#{env_prefix}_DATABASE_PASSWORD"] || ENV['DATABASE_PASSWORD'] || 'mondrian_test'
18
18
  DATABASE_NAME = ENV["#{env_prefix}_DATABASE_NAME"] || ENV['DATABASE_NAME'] || 'mondrian_test'
19
19
  DATABASE_INSTANCE = ENV["#{env_prefix}_DATABASE_INSTANCE"] || ENV['DATABASE_INSTANCE']
20
20
 
21
21
  case MONDRIAN_DRIVER
22
22
  when 'mysql', 'jdbc_mysql'
23
- require 'jdbc/mysql'
24
- JDBC_DRIVER = 'com.mysql.jdbc.Driver'
23
+ if jdbc_driver_file = Dir[File.expand_path("mysql*.jar", 'spec/support/jars')].first
24
+ require jdbc_driver_file
25
+ else
26
+ require 'jdbc/mysql'
27
+ end
28
+ JDBC_DRIVER = (Java::com.mysql.cj.jdbc.Driver rescue nil) ? 'com.mysql.cj.jdbc.Driver' : 'com.mysql.jdbc.Driver'
29
+
25
30
  when 'postgresql'
26
31
  require 'jdbc/postgres'
27
32
  JDBC_DRIVER = 'org.postgresql.Driver'
33
+ require 'arjdbc/postgresql'
34
+
28
35
  when 'oracle'
36
+ Dir[File.expand_path("ojdbc*.jar", 'spec/support/jars')].each do |jdbc_driver_file|
37
+ require jdbc_driver_file
38
+ end
29
39
  require 'active_record/connection_adapters/oracle_enhanced_adapter'
40
+ ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval do
41
+ # Start primary key sequences from 1 (and not 10000) and take just one next value in each session
42
+ self.default_sequence_start_value = "1 NOCACHE INCREMENT BY 1"
43
+ # PATCH: Restore previous mapping of ActiveRecord datetime to DATE type.
44
+ def supports_datetime_with_precision?; false; end
45
+ # PATCH: Do not send fractional seconds to DATE type.
46
+ def quoted_date(value)
47
+ if value.acts_like?(:time)
48
+ zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
49
+ if value.respond_to?(zone_conversion_method)
50
+ value = value.send(zone_conversion_method)
51
+ end
52
+ end
53
+ value.to_s(:db)
54
+ end
55
+ private
56
+ # PATCH: Restore previous mapping of ActiveRecord datetime to DATE type.
57
+ const_get(:NATIVE_DATABASE_TYPES)[:datetime] = {name: "DATE"}
58
+ alias_method :original_initialize_type_map, :initialize_type_map
59
+ def initialize_type_map(m = type_map)
60
+ original_initialize_type_map(m)
61
+ # PATCH: Map Oracle DATE to DateTime for backwards compatibility
62
+ register_class_with_precision m, %r(date)i, ActiveRecord::Type::DateTime
63
+ end
64
+ end
30
65
  CATALOG_FILE = File.expand_path('../fixtures/MondrianTestOracle.xml', __FILE__)
31
- when 'mssql'
32
- require 'jdbc/jtds'
33
- JDBC_DRIVER = 'net.sourceforge.jtds.jdbc.Driver'
66
+
34
67
  when 'sqlserver'
35
- Dir[File.expand_path("{mssql-jdbc,sqljdbc}*.jar", 'spec/support/jars')].each do |jdbc_driver_file|
68
+ Dir[File.expand_path("mssql-jdbc*.jar", 'spec/support/jars')].each do |jdbc_driver_file|
36
69
  require jdbc_driver_file
37
70
  end
71
+ require 'arjdbc/jdbc/adapter'
72
+ ActiveRecord::ConnectionAdapters::JdbcAdapter.class_eval do
73
+ def initialize(connection, logger = nil, connection_parameters = nil, config = {})
74
+ super(connection, logger, config.dup)
75
+ end
76
+ def modify_types(types)
77
+ types.merge!(
78
+ primary_key: 'bigint NOT NULL IDENTITY(1,1) PRIMARY KEY',
79
+ integer: {name: 'int'},
80
+ bigint: {name: 'bigint'},
81
+ boolean: {name: 'bit'},
82
+ decimal: {name: 'decimal'},
83
+ date: {name: 'date'},
84
+ datetime: {name: 'datetime'},
85
+ timestamp: {name: 'datetime'},
86
+ string: {name: 'nvarchar', limit: 4000},
87
+ text: {name: 'nvarchar(max)'}
88
+ )
89
+ end
90
+ def quote_table_name(name)
91
+ name.to_s.split('.').map { |n| quote_column_name(n) }.join('.')
92
+ end
93
+ def quote_column_name(name)
94
+ "[#{name.to_s}]"
95
+ end
96
+ def columns(table_name, name = nil)
97
+ select_all(
98
+ "SELECT * FROM information_schema.columns WHERE table_name = #{quote table_name}"
99
+ ).map do |column|
100
+ ActiveRecord::ConnectionAdapters::Column.new(
101
+ column['COLUMN_NAME'],
102
+ column['COLUMN_DEFAULT'],
103
+ fetch_type_metadata(column['DATA_TYPE']),
104
+ column['IS_NULLABLE']
105
+ )
106
+ end
107
+ end
108
+ def write_query?(sql)
109
+ sql =~ /\A(INSERT|UPDATE|DELETE) /
110
+ end
111
+ end
112
+ ::Arel::Visitors::ToSql.class_eval do
113
+ private
114
+ def visit_Arel_Nodes_Limit(o, collector)
115
+ # Do not add LIMIT as it is not supported by MS SQL Server
116
+ collector
117
+ end
118
+ end
119
+ require "active_model/type/integer"
120
+ ActiveModel::Type::Integer::DEFAULT_LIMIT = 8
38
121
  JDBC_DRIVER = 'com.microsoft.sqlserver.jdbc.SQLServerDriver'
122
+
39
123
  when 'vertica'
40
124
  Dir[File.expand_path("vertica*.jar", 'spec/support/jars')].each do |jdbc_driver_file|
41
125
  require jdbc_driver_file
42
126
  end
43
127
  JDBC_DRIVER = 'com.vertica.jdbc.Driver'
44
128
  DATABASE_SCHEMA = ENV["#{env_prefix}_DATABASE_SCHEMA"] || ENV['DATABASE_SCHEMA'] || 'mondrian_test'
45
- # patches for Vertica minimal AR support
46
129
  require 'arjdbc/jdbc/adapter'
47
130
  ActiveRecord::ConnectionAdapters::JdbcAdapter.class_eval do
48
- def modify_types(tp)
49
- # mapping of ActiveRecord data types to Vertica data types
50
- tp[:primary_key] = "identity"
51
- tp[:integer] = "int"
131
+ def initialize(connection, logger = nil, connection_parameters = nil, config = {})
132
+ super(connection, logger, config.dup)
133
+ end
134
+ def modify_types(types)
135
+ types[:primary_key] = "int" # Use int instead of identity as data cannot be loaded into identity columns
136
+ types[:integer] = "int"
137
+ end
138
+ def type_to_sql(type, limit: nil, precision: nil, scale: nil, **)
139
+ case type.to_sym
140
+ when :integer, :primary_key
141
+ 'int' # All integers are 64-bit in Vertica and limit should be ignored
142
+ else
143
+ super
144
+ end
52
145
  end
53
- # by default Vertica stores table and column names in uppercase
146
+ # By default Vertica stores table and column names in uppercase
54
147
  def quote_table_name(name)
55
148
  "\"#{name.to_s}\""
56
149
  end
@@ -62,6 +155,7 @@ when 'vertica'
62
155
  exec_update(sql, name, binds)
63
156
  end
64
157
  end
158
+
65
159
  when 'snowflake'
66
160
  Dir[File.expand_path("snowflake*.jar", 'spec/support/jars')].each do |jdbc_driver_file|
67
161
  require jdbc_driver_file
@@ -72,166 +166,290 @@ when 'snowflake'
72
166
  CATALOG_FILE = File.expand_path('../fixtures/MondrianTestOracle.xml', __FILE__)
73
167
  require 'arjdbc/jdbc/adapter'
74
168
  ActiveRecord::ConnectionAdapters::JdbcAdapter.class_eval do
75
- def modify_types(tp)
76
- # mapping of ActiveRecord data types to Snowflake data types
77
- tp[:primary_key] = "integer"
78
- tp[:integer] = "integer"
169
+ def initialize(connection, logger = nil, connection_parameters = nil, config = {})
170
+ super(connection, logger, config.dup)
171
+ end
172
+ def modify_types(types)
173
+ types[:primary_key] = 'integer'
174
+ types[:integer] = 'integer'
175
+ end
176
+ # exec_insert tries to use Statement.RETURN_GENERATED_KEYS which is not supported by Snowflake
177
+ def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
178
+ exec_update(sql, name, binds)
79
179
  end
80
180
  end
81
181
  require 'arjdbc/jdbc/type_converter'
82
182
  # Hack to disable :text and :binary types for Snowflake
83
183
  ActiveRecord::ConnectionAdapters::JdbcTypeConverter::AR_TO_JDBC_TYPES.delete(:text)
84
184
  ActiveRecord::ConnectionAdapters::JdbcTypeConverter::AR_TO_JDBC_TYPES.delete(:binary)
85
- when 'luciddb'
86
- require 'jdbc/luciddb'
87
- CATALOG_FILE = File.expand_path('../fixtures/MondrianTestOracle.xml', __FILE__)
88
185
 
89
- # Hack to disable :text type for LucidDB
90
- require 'arjdbc/jdbc/type_converter'
91
- ActiveRecord::ConnectionAdapters::JdbcTypeConverter::AR_TO_JDBC_TYPES.delete(:text)
186
+ when 'clickhouse'
187
+ Dir[File.expand_path("clickhouse*.jar", 'spec/support/jars')].each do |jdbc_driver_file|
188
+ require jdbc_driver_file
189
+ end
190
+ JDBC_DRIVER = 'com.clickhouse.jdbc.ClickHouseDriver'
191
+ DATABASE_SCHEMA = ENV["#{env_prefix}_DATABASE_SCHEMA"] || ENV['DATABASE_SCHEMA'] || 'mondrian_test'
192
+ require 'arjdbc/jdbc/adapter'
193
+ ActiveRecord::ConnectionAdapters::JdbcAdapter.class_eval do
194
+ def initialize(connection, logger = nil, connection_parameters = nil, config = {})
195
+ super(connection, logger, config.dup)
196
+ end
197
+ NATIVE_DATABASE_TYPES = {
198
+ primary_key: "Int32", # We do not need automatic primary key generation and need to allow inserting PK values
199
+ string: {name: "String"},
200
+ text: {name: "String"},
201
+ integer: {name: "Int32"},
202
+ float: {name: "Float64"},
203
+ numeric: {name: "Decimal"},
204
+ decimal: {name: "Decimal"},
205
+ datetime: {name: "DateTime"},
206
+ timestamp: {name: "DateTime"},
207
+ time: {name: "DateTime"},
208
+ date: {name: "Date"},
209
+ binary: {name: "String"},
210
+ boolean: {name: "Boolean"},
211
+ }
212
+ def native_database_types
213
+ NATIVE_DATABASE_TYPES
214
+ end
215
+ def modify_types(types)
216
+ types[:primary_key] = 'Int32'
217
+ types[:integer] = 'Int32'
218
+ end
219
+ def type_to_sql(type, limit: nil, precision: nil, scale: nil, **)
220
+ case type.to_sym
221
+ when :integer, :primary_key
222
+ return 'Int32' unless limit
223
+ case limit.to_i
224
+ when 1 then 'Int8'
225
+ when 2 then 'Int16'
226
+ when 3, 4 then 'Int32'
227
+ when 5..8 then 'Int64'
228
+ else raise ActiveRecord::ActiveRecordError,
229
+ "No integer type has byte size #{limit}. Use a numeric with precision 0 instead."
230
+ end
231
+ # Ignore limit for string and text
232
+ when :string, :text
233
+ super(type)
234
+ else
235
+ super
236
+ end
237
+ end
238
+ def quote_table_name(name)
239
+ "`#{name.to_s}`"
240
+ end
241
+ def quote_column_name(name)
242
+ "`#{name.to_s}`"
243
+ end
244
+ def create_table(name, options = {})
245
+ super(name, {options: "ENGINE=MergeTree ORDER BY tuple()"}.merge(options))
246
+ end
247
+ alias_method :exec_update_original, :exec_update
248
+ # exec_insert tries to use Statement.RETURN_GENERATED_KEYS which is not supported by ClickHouse
249
+ def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
250
+ exec_update_original(sql, name, binds)
251
+ end
252
+ # Modify UPDATE statements for ClickHouse specific syntax
253
+ def exec_update(sql, name, binds)
254
+ if sql =~ /\AUPDATE (.*) SET (.*)\z/
255
+ sql = "ALTER TABLE #{$1} UPDATE #{$2}"
256
+ end
257
+ exec_update_original(sql, name, binds)
258
+ end
259
+ end
92
260
 
93
- # patches for LucidDB minimal AR support
261
+ when 'mariadb'
262
+ Dir[File.expand_path("mariadb*.jar", 'spec/support/jars')].each do |jdbc_driver_file|
263
+ require jdbc_driver_file
264
+ end
265
+ JDBC_DRIVER = 'org.mariadb.jdbc.Driver'
94
266
  require 'arjdbc/jdbc/adapter'
95
267
  ActiveRecord::ConnectionAdapters::JdbcAdapter.class_eval do
96
- def modify_types(tp)
97
- # mapping of ActiveRecord data types to LucidDB data types
98
- # data will be imported into LucidDB therefore primary key is defined as simple integer field
99
- tp[:primary_key] = "INT"
100
- tp[:integer] = "INT"
268
+ def initialize(connection, logger = nil, connection_parameters = nil, config = {})
269
+ super(connection, logger, config.dup)
270
+ end
271
+ def modify_types(types)
272
+ types[:primary_key] = "integer"
273
+ types[:integer] = "integer"
274
+ end
275
+ def type_to_sql(type, limit: nil, precision: nil, scale: nil, **)
276
+ case type.to_sym
277
+ when :integer, :primary_key
278
+ return 'integer' unless limit
279
+ case limit.to_i
280
+ when 1 then 'tinyint'
281
+ when 2 then 'smallint'
282
+ when 3 then 'mediumint'
283
+ when 4 then 'integer'
284
+ when 5..8 then 'bigint'
285
+ else raise ActiveRecord::ActiveRecordError,
286
+ "No integer type has byte size #{limit}. Use a numeric with precision 0 instead."
287
+ end
288
+ when :text
289
+ case limit
290
+ when 0..0xff then 'tinytext'
291
+ when nil, 0x100..0xffff then 'text'
292
+ when 0x10000..0xffffff then'mediumtext'
293
+ when 0x1000000..0xffffffff then 'longtext'
294
+ else raise ActiveRecordError, "No text type has character length #{limit}"
295
+ end
296
+ else
297
+ super
298
+ end
101
299
  end
102
- # by default LucidDB stores table and column names in uppercase
103
300
  def quote_table_name(name)
104
- "\"#{name.to_s.upcase}\""
301
+ "`#{name.to_s}`"
105
302
  end
106
303
  def quote_column_name(name)
107
- "\"#{name.to_s.upcase}\""
304
+ "`#{name.to_s}`"
305
+ end
306
+ def execute(sql, name = nil, binds = nil)
307
+ exec_update(sql, name, binds)
308
+ end
309
+ def create_table(name, options = {})
310
+ super(name, {options: "ENGINE=Columnstore DEFAULT CHARSET=utf8"}.merge(options))
108
311
  end
109
312
  end
110
- JDBC_DRIVER = 'org.luciddb.jdbc.LucidDbClientDriver'
111
- DATABASE_USER.upcase! if DATABASE_USER == 'mondrian_test'
112
- DATABASE_NAME = nil
113
- DATABASE_SCHEMA = ENV['DATABASE_SCHEMA'] || 'mondrian_test'
114
313
  end
115
314
 
116
315
  puts "==> Using #{MONDRIAN_DRIVER} driver"
117
316
 
317
+ # Necessary for Aggregate optimizations test
318
+ Java::JavaLang::System.setProperty("mondrian.rolap.EnableInMemoryRollup", "false")
319
+
118
320
  require 'mondrian/olap'
119
321
  require_relative 'support/matchers/be_like'
120
322
 
121
323
  RSpec.configure do |config|
122
324
  config.include Matchers
325
+ config.expect_with(:rspec) { |c| c.syntax = [:should, :expect] }
123
326
  end
124
327
 
125
328
  CATALOG_FILE = File.expand_path('../fixtures/MondrianTest.xml', __FILE__) unless defined?(CATALOG_FILE)
126
329
 
127
330
  CONNECTION_PARAMS = if MONDRIAN_DRIVER =~ /^jdbc/
128
331
  {
129
- :driver => 'jdbc',
130
- :jdbc_url => "jdbc:#{MONDRIAN_DRIVER.split('_').last}://#{DATABASE_HOST}/#{DATABASE_NAME}",
131
- :jdbc_driver => JDBC_DRIVER,
132
- :username => DATABASE_USER,
133
- :password => DATABASE_PASSWORD
332
+ driver: 'jdbc',
333
+ jdbc_url: "jdbc:#{MONDRIAN_DRIVER.split('_').last}://#{DATABASE_HOST}/#{DATABASE_NAME}",
334
+ jdbc_driver: JDBC_DRIVER,
335
+ username: DATABASE_USER,
336
+ password: DATABASE_PASSWORD
134
337
  }
135
338
  else
136
339
  {
137
- # uncomment to test PostgreSQL SSL connection
138
- # :properties => {'ssl'=>'true','sslfactory'=>'org.postgresql.ssl.NonValidatingFactory'},
139
- :driver => MONDRIAN_DRIVER,
140
- :host => DATABASE_HOST,
141
- :database => DATABASE_NAME,
142
- :username => DATABASE_USER,
143
- :password => DATABASE_PASSWORD
144
- }
340
+ # Uncomment to test PostgreSQL SSL connection
341
+ # properties: {'ssl'=>'true','sslfactory'=>'org.postgresql.ssl.NonValidatingFactory'},
342
+ driver: MONDRIAN_DRIVER,
343
+ host: DATABASE_HOST,
344
+ port: DATABASE_PORT,
345
+ protocol: DATABASE_PROTOCOL.presence,
346
+ database: DATABASE_NAME,
347
+ username: DATABASE_USER,
348
+ password: DATABASE_PASSWORD
349
+ }.compact
350
+ end
351
+ case MONDRIAN_DRIVER
352
+ when 'mysql'
353
+ CONNECTION_PARAMS[:properties] = {useSSL: false, serverTimezone: 'UTC'}
354
+ when 'jdbc_mysql'
355
+ CONNECTION_PARAMS[:jdbc_url] << '?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC'
145
356
  end
146
357
 
147
358
  case MONDRIAN_DRIVER
359
+ when 'mysql', 'postgresql'
360
+ AR_CONNECTION_PARAMS = CONNECTION_PARAMS.slice(:host, :database, :username, :password).merge(
361
+ adapter: MONDRIAN_DRIVER,
362
+ driver: JDBC_DRIVER,
363
+ properties: CONNECTION_PARAMS[:properties].dup || {}
364
+ )
148
365
  when 'oracle'
149
366
  AR_CONNECTION_PARAMS = {
150
- :adapter => 'oracle_enhanced',
151
- :host => CONNECTION_PARAMS[:host],
152
- :database => CONNECTION_PARAMS[:database],
153
- :username => CONNECTION_PARAMS[:username],
154
- :password => CONNECTION_PARAMS[:password]
155
- }
156
- when 'luciddb'
157
- CONNECTION_PARAMS[:database] = nil
158
- CONNECTION_PARAMS[:database_schema] = DATABASE_SCHEMA
159
- AR_CONNECTION_PARAMS = {
160
- :adapter => 'jdbc',
161
- :driver => JDBC_DRIVER,
162
- :url => "jdbc:#{MONDRIAN_DRIVER}:http://#{CONNECTION_PARAMS[:host]};schema=#{CONNECTION_PARAMS[:database_schema]}",
163
- :username => CONNECTION_PARAMS[:username],
164
- :password => CONNECTION_PARAMS[:password]
165
- }
166
- when 'mssql'
167
- url = "jdbc:jtds:sqlserver://#{CONNECTION_PARAMS[:host]}/#{CONNECTION_PARAMS[:database]}"
168
- url << ";instance=#{DATABASE_INSTANCE}" if DATABASE_INSTANCE
169
- AR_CONNECTION_PARAMS = {
170
- :adapter => 'jdbc',
171
- :dialect => 'Microsoft SQL Server',
172
- :driver => JDBC_DRIVER,
173
- :url => url,
174
- :username => CONNECTION_PARAMS[:username],
175
- :password => CONNECTION_PARAMS[:password],
176
- :connection_alive_sql => 'SELECT 1'
367
+ adapter: 'oracle_enhanced',
368
+ host: CONNECTION_PARAMS[:host],
369
+ database: CONNECTION_PARAMS[:database],
370
+ username: CONNECTION_PARAMS[:username],
371
+ password: CONNECTION_PARAMS[:password],
372
+ nls_numeric_characters: '.,'
177
373
  }
178
374
  when 'sqlserver'
179
375
  url = "jdbc:sqlserver://#{CONNECTION_PARAMS[:host]};databaseName=#{CONNECTION_PARAMS[:database]};"
180
376
  url << ";instanceName=#{DATABASE_INSTANCE}" if DATABASE_INSTANCE
181
377
  AR_CONNECTION_PARAMS = {
182
- :adapter => 'jdbc',
183
- :driver => JDBC_DRIVER,
184
- :url => url,
185
- :username => CONNECTION_PARAMS[:username],
186
- :password => CONNECTION_PARAMS[:password],
187
- :connection_alive_sql => 'SELECT 1'
378
+ adapter: 'jdbc',
379
+ driver: JDBC_DRIVER,
380
+ url: url,
381
+ username: CONNECTION_PARAMS[:username],
382
+ password: CONNECTION_PARAMS[:password],
383
+ connection_alive_sql: 'SELECT 1',
384
+ sqlserver_version: ENV['SQLSERVER_VERSION'],
385
+ dialect: 'jdbc'
188
386
  }
189
387
  when 'vertica'
388
+ CONNECTION_PARAMS[:properties] = {
389
+ 'SearchPath' => DATABASE_SCHEMA
390
+ }
190
391
  AR_CONNECTION_PARAMS = {
191
392
  adapter: 'jdbc',
192
- driver: JDBC_DRIVER,
193
- url: "jdbc:#{MONDRIAN_DRIVER}://#{CONNECTION_PARAMS[:host]}/#{CONNECTION_PARAMS[:database]}?SearchPath=#{DATABASE_SCHEMA}&LogLevel=DEBUG",
393
+ driver: JDBC_DRIVER,
394
+ url: "jdbc:#{MONDRIAN_DRIVER}://#{CONNECTION_PARAMS[:host]}/#{CONNECTION_PARAMS[:database]}" \
395
+ "?SearchPath=#{DATABASE_SCHEMA}", # &LogLevel=DEBUG
194
396
  username: CONNECTION_PARAMS[:username],
195
- password: CONNECTION_PARAMS[:password]
397
+ password: CONNECTION_PARAMS[:password],
398
+ dialect: 'jdbc'
196
399
  }
197
400
  when 'snowflake'
198
401
  CONNECTION_PARAMS[:database_schema] = DATABASE_SCHEMA
199
402
  CONNECTION_PARAMS[:warehouse] = WAREHOUSE_NAME
403
+ CONNECTION_PARAMS[:properties] = {
404
+ # 'tracing' => 'ALL'
405
+ }
406
+ AR_CONNECTION_PARAMS = {
407
+ adapter: 'jdbc',
408
+ driver: JDBC_DRIVER,
409
+ url: "jdbc:#{MONDRIAN_DRIVER}://#{CONNECTION_PARAMS[:host]}/?db=#{CONNECTION_PARAMS[:database]}" \
410
+ "&schema=#{DATABASE_SCHEMA}&warehouse=#{WAREHOUSE_NAME}", # &tracing=ALL
411
+ username: CONNECTION_PARAMS[:username],
412
+ password: CONNECTION_PARAMS[:password],
413
+ dialect: 'jdbc'
414
+ }
415
+ when 'clickhouse'
416
+ # CREATE USER mondrian_test IDENTIFIED WITH plaintext_password BY 'mondrian_test';
417
+ # CREATE DATABASE mondrian_test;
418
+ # GRANT ALL ON mondrian_test.* TO mondrian_test;
419
+
420
+ # For testing different protocols
421
+ # CONNECTION_PARAMS[:protocol] = 'http'
422
+ # CONNECTION_PARAMS[:properties] ={'http_connection_provider' => 'APACHE_HTTP_CLIENT'}
423
+
200
424
  AR_CONNECTION_PARAMS = {
201
425
  adapter: 'jdbc',
202
- driver: JDBC_DRIVER,
203
- url: "jdbc:#{MONDRIAN_DRIVER}://#{CONNECTION_PARAMS[:host]}/?db=#{CONNECTION_PARAMS[:database]}&schema=#{DATABASE_SCHEMA}&warehouse=#{WAREHOUSE_NAME}&tracing=ALL",
426
+ driver: JDBC_DRIVER,
427
+ url: "jdbc:ch:#{CONNECTION_PARAMS[:protocol]&.+(':')}//#{CONNECTION_PARAMS[:host]}/#{CONNECTION_PARAMS[:database]}",
204
428
  username: CONNECTION_PARAMS[:username],
205
- password: CONNECTION_PARAMS[:password]
429
+ password: CONNECTION_PARAMS[:password],
430
+ dialect: 'jdbc'
206
431
  }
207
432
  when /jdbc/
208
433
  AR_CONNECTION_PARAMS = {
209
- :adapter => 'jdbc',
210
- :driver => JDBC_DRIVER,
211
- :url => CONNECTION_PARAMS[:jdbc_url],
212
- :username => CONNECTION_PARAMS[:username],
213
- :password => CONNECTION_PARAMS[:password]
434
+ adapter: MONDRIAN_DRIVER =~ /mysql/ ? 'mysql' : 'jdbc',
435
+ driver: JDBC_DRIVER,
436
+ url: CONNECTION_PARAMS[:jdbc_url],
437
+ username: CONNECTION_PARAMS[:username],
438
+ password: CONNECTION_PARAMS[:password],
439
+ dialect: MONDRIAN_DRIVER =~ /mysql/ ? 'mysql' : 'jdbc'
214
440
  }
215
441
  else
216
442
  AR_CONNECTION_PARAMS = {
217
- # uncomment to test PostgreSQL SSL connection
218
- # :properties => CONNECTION_PARAMS[:properties],
219
- :adapter => 'jdbc',
220
- :driver => JDBC_DRIVER,
221
- :url => "jdbc:#{MONDRIAN_DRIVER}://#{CONNECTION_PARAMS[:host]}/#{CONNECTION_PARAMS[:database]}",
222
- :username => CONNECTION_PARAMS[:username],
223
- :password => CONNECTION_PARAMS[:password]
443
+ adapter: 'jdbc',
444
+ driver: JDBC_DRIVER,
445
+ url: "jdbc:#{MONDRIAN_DRIVER}://#{CONNECTION_PARAMS[:host]}" +
446
+ (CONNECTION_PARAMS[:port] ? ":#{CONNECTION_PARAMS[:port]}" : "") + "/#{CONNECTION_PARAMS[:database]}",
447
+ username: CONNECTION_PARAMS[:username],
448
+ password: CONNECTION_PARAMS[:password],
449
+ dialect: 'jdbc'
224
450
  }
225
451
  end
226
452
 
227
- # Avoid "Establishing SSL connection without server's identity verification ..." warnings
228
- case MONDRIAN_DRIVER
229
- when 'mysql'
230
- AR_CONNECTION_PARAMS[:properties] = CONNECTION_PARAMS[:properties] = {useSSL: false}
231
- when 'jdbc_mysql'
232
- AR_CONNECTION_PARAMS[:url] = CONNECTION_PARAMS[:jdbc_url] << '?useSSL=false'
233
- end
234
-
235
- CONNECTION_PARAMS_WITH_CATALOG = CONNECTION_PARAMS.merge(:catalog => CATALOG_FILE)
453
+ CONNECTION_PARAMS_WITH_CATALOG = CONNECTION_PARAMS.merge(catalog: CATALOG_FILE)
236
454
 
237
455
  ActiveRecord::Base.establish_connection(AR_CONNECTION_PARAMS)