mondrian-olap 1.1.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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)