aleph_analytics 0.3.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9d4c390667cb9196104ad61049e9028d01b906ca
4
- data.tar.gz: 5a4d2383a969bdb45929b8b696e491f61f42867c
3
+ metadata.gz: 7e1db8aa9b5d9683d749e21595c0f3060311cf4e
4
+ data.tar.gz: 6e0f9d737de278e1cc20bfb93b8390f24f142879
5
5
  SHA512:
6
- metadata.gz: e88f4a7c419aa95cff8f1ded63c50c1da317022a82e3a8242458d55f4f66789d86ffe559ae2278b1c66e47f4e1a75ef44203af9e0a40a8bc4a3fca10f7f7faa9
7
- data.tar.gz: f5e2da4929c25d8831812e452566e7f1ab68aeeed4dc95dde2d2ebcef7a5a682958a68be9ba121b1d2b36e6c41e6e618f9cb50381a3f4298cf1b12c3c5dc497c
6
+ metadata.gz: 1bfcbc8ed2830c89b53d21ba77db6a877981f72f1224cd01dfdf6bdb60e44b1ca249a42a247c3835e5bc249e931fbd3fb5d8e2c304da078604dba0d92c88a30f
7
+ data.tar.gz: 6ea247ebd88fcc9aa83ab22fc2ae7c6283c0a79aa7fd429d74f6154eacf9828e549d418ac7f9a418ff626da5019410958c0cb252f56e64744c5e9179e0ee2b1d
@@ -1,7 +1,15 @@
1
1
  # Change Log
2
2
  All notable changes to this project will be documented in this file using [Semantic Versioning](http://semver.org/).
3
3
 
4
- ## [0.3.0] - 2010-02-26
4
+ ## [0.4.1] - 2019-09-10
5
+ ### Fixed
6
+ - [Bug fixes for v0.4.0](https://github.com/lumoslabs/aleph/pull/89)
7
+
8
+ ## [0.4.0] - 2019-09-02
9
+ ### Features
10
+ - Added support for Snowflake
11
+
12
+ ## [0.3.0] - 2019-02-26
5
13
  ### Features
6
14
  - [Scheduled Query Execution](https://github.com/lumoslabs/aleph/issues/42)
7
15
  - Fixed s3 location for latest result (useful for GoogleSheet integration)
data/Gemfile CHANGED
@@ -36,7 +36,9 @@ gem 'resque-pool', '~> 0.5.0'
36
36
  gem 'resque-web', '0.0.6', require: 'resque_web'
37
37
  gem 'roar'
38
38
  gem 'rollbar', '~> 2.3.0'
39
+ gem 'ruby-odbc'
39
40
  gem 'sass-rails'
41
+ gem 'sequel', '~> 4.35'
40
42
  gem 'sprockets-es6', '~> 0.8.0'
41
43
  gem 'therubyracer'
42
44
  gem 'thin'
@@ -338,6 +338,7 @@ GEM
338
338
  rspec-mocks (~> 3.3.0)
339
339
  rspec-support (~> 3.3.0)
340
340
  rspec-support (3.3.0)
341
+ ruby-odbc (0.99999)
341
342
  ruby-saml (1.0.0)
342
343
  nokogiri (>= 1.5.10)
343
344
  uuid (~> 2.3)
@@ -349,6 +350,7 @@ GEM
349
350
  sprockets (>= 2.8, < 4.0)
350
351
  sprockets-rails (>= 2.0, < 4.0)
351
352
  tilt (>= 1.1, < 3)
353
+ sequel (4.49.0)
352
354
  sham_rack (1.3.6)
353
355
  rack
354
356
  shoulda-matchers (3.0.0)
@@ -473,7 +475,9 @@ DEPENDENCIES
473
475
  roar
474
476
  rollbar (~> 2.3.0)
475
477
  rspec-rails
478
+ ruby-odbc
476
479
  sass-rails
480
+ sequel (~> 4.35)
477
481
  sham_rack
478
482
  shoulda-matchers
479
483
  sprockets-es6 (~> 0.8.0)
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  # Aleph
3
- Aleph is a Redshift analytics platform that focuses on aggregating institutional data investigation techniques.
3
+ Aleph is a business analytics platform that focuses on ease-of-use and operational simplicity. It allows analysts to quickly author and iterate on queries, then share result sets and visualizations. Most components are modular, but it was designed to version-control queries (and analyze their differences) using Github and store result sets long term in Amazon S3.
4
4
 
5
5
  ![aleph](images/aleph_repo_banner.png)
6
6
 
@@ -13,15 +13,30 @@ Aleph is a Redshift analytics platform that focuses on aggregating institutional
13
13
 
14
14
 
15
15
  ## Quickstart
16
- If you want to connect to your own Redshift cluster, the follow instructions should get you up and running.
16
+ If you want to connect to your own Redshift or Snowflake cluster, the follow instructions should get you up and running.
17
+
18
+ ### Database Configuration
19
+ Configure your Redshift or snowflake database and user(s).
20
+
21
+ ###### Additional requirements for Snowflake
22
+ * Snowflake users must be setup with default warehouse and role; they are not configurable in Alpeh.
23
+ * Since Aleph query results are unloaded directly from Snowflake to AWS S3, S3 is required for Snowflake connection.
24
+ Configure an S3 bucket and create an external S3 stage in Snowflake. e.g.
25
+
26
+ create stage mydb.myschema.aleph_stage url='s3://<s3_bucket>/<path>/'
27
+ credentials=(aws_role = '<iam role>')
17
28
 
18
29
  ### Docker Install
19
30
  The fastest way to get started: [Docker](https://docs.docker.com/mac/step_one/)
20
31
 
21
- ###### Configure your Redshift and run
32
+ * For Redshift, run
22
33
 
23
34
  docker run -ti -p 3000:3000 lumos/aleph-playground /bin/bash -c "aleph setup_minimal -H {host} -D {db} -p {port} -U {user} -P {password}; redis-server & aleph run_demo"
24
35
 
36
+ * For Snowflake, run
37
+
38
+ docker run -ti -p 3000:3000 lumos/aleph-snowflake-playground /bin/bash -c "export AWS_ACCESS_KEY_ID=\"{aws_key_id}\" ; export AWS_SECRET_ACCESS_KEY=\"{aws_secret_key}\" ; cd /usr/bin/snowflake_odbc && sed -i 's/SF_ACCOUNT/{your_snowflake_account}/g' ./unixodbc_setup.sh && ./unixodbc_setup.sh && aleph setup_minimal -t snowflake -S snowflake -U {user} -P {password} -L {snowflake_unload_target} -R {s3_region} -B {s3_bucket} -F {s3_folder}; redis-server & aleph run_demo"
39
+ `snowflake_unload_target` is the external stage and location in snowflake. e.g. `@mydb.myschema.aleph_stage/results/`
25
40
 
26
41
  ###### Open in browser
27
42
 
@@ -29,8 +44,17 @@ The fastest way to get started: [Docker](https://docs.docker.com/mac/step_one/)
29
44
 
30
45
  ### Gem Install
31
46
 
47
+ ###### For Redshift
32
48
  You must be using [PostgreSQL 9.2beta3 or later client libraries](https://kkob.us/2014/12/20/homebrew-and-postgresql-9-4/)
33
49
 
50
+ ###### For Snowflake
51
+ You must install `unixodbc-dev` and setup and configure [snowflake ODBC](https://docs.snowflake.net/manuals/user-guide/odbc.html). e.g.
52
+
53
+ apt-get update && apt-get install -y unixodbc-dev
54
+ curl -o /tmp/snowflake_linux_x8664_odbc-2.19.8.tgz https://sfc-repo.snowflakecomputing.com/odbc/linux/latest/snowflake_linux_x8664_odbc-2.19.8.tgz && cd /tmp && gunzip snowflake_linux_x8664_odbc-2.19.8.tgz && tar -xvf snowflake_linux_x8664_odbc-2.19.8.tar && cp -r snowflake_odbc /usr/bin && rm -r /tmp/snowflake_odbc
55
+ cd /usr/bin/snowflake_odbc
56
+ ./unixodbc_setup.sh # and following the instructions to setup Snowflake DSN
57
+
34
58
  ###### Install and run Redis
35
59
 
36
60
  brew install redis && redis-server &
@@ -39,11 +63,22 @@ You must be using [PostgreSQL 9.2beta3 or later client libraries](https://kkob.u
39
63
 
40
64
  gem install aleph_analytics
41
65
 
42
- ###### Configure your Redshift and run
66
+ ###### Configure your database
67
+ See [Database Configuration](#database-configuration) above
68
+
69
+ ###### Run Aleph
70
+ * For Redshift
43
71
 
44
- aleph setup_minimal -H {host} -D {db} -p {port} -U {user} -P {password}
45
- aleph run_demo
72
+ aleph setup_minimal -H {host} -D {db} -p {port} -U {user} -P {password}
73
+ aleph run_demo
46
74
 
75
+ * For Snowflake
76
+
77
+ export AWS_ACCESS_KEY_ID="{aws key id}"
78
+ export AWS_SECRET_ACCESS_KEY="{aws secret key}"
79
+ aleph setup_minimal -t snowflake -S snowflake -U {user} -P {password} -L {snowflake_unload_target} -R {s3_region} -B {s3_bucket} -F {s3_folder}
80
+ aleph run_demo
81
+
47
82
  Aleph should be running at `localhost:3000`
48
83
 
49
84
  ## Aleph Gem
@@ -60,11 +95,17 @@ For a proper production installation, Aleph needs an external Redis instance and
60
95
  ### The app
61
96
  There are a number of ways to install and deploy Aleph. The simplest is to set up a Dockerfile that installs aleph as a gem:
62
97
 
63
- FROM ruby:2.1.6
98
+ FROM ruby:2.2.4
64
99
 
65
- # we need postgres client libs
100
+ # we need postgres client libs for Redshift
66
101
  RUN apt-get update && apt-get install -y postgresql-client --no-install-recommends && rm -rf /var/lib/apt/lists/*
67
102
 
103
+ # for Snowflake, install unix odbc and Snowflake ODBC driver and setup DSN
104
+ # replace {your snowflake account} below
105
+ RUN apt-get update && apt-get install -y unixodbc-dev
106
+ RUN curl -o /tmp/snowflake_linux_x8664_odbc-2.19.8.tgz https://sfc-repo.snowflakecomputing.com/odbc/linux/latest/snowflake_linux_x8664_odbc-2.19.8.tgz && cd /tmp && gunzip snowflake_linux_x8664_odbc-2.19.8.tgz && tar -xvf snowflake_linux_x8664_odbc-2.19.8.tar && cp -r snowflake_odbc /usr/bin && rm -r /tmp/snowflake_odbc
107
+ RUN cd /usr/bin/snowflake_odbc && sed -i 's/SF_ACCOUNT/{your snowflake account}/g' ./unixodbc_setup.sh && ./unixodbc_setup.sh
108
+
68
109
  # make a log location
69
110
  RUN mkdir -p /var/log/aleph
70
111
  ENV SERVER_LOG_ROOT /var/log/aleph
@@ -91,10 +132,15 @@ You can then deploy and run the main components of Aleph as separate services us
91
132
 
92
133
  At runtime, you can inject all the secrets as environment variables.
93
134
 
94
- We *highly* recommend that you have a git repo for your queries and s3 location for you results.
135
+ S3 is required for Snowflake.
136
+
137
+ We *highly* recommend that you have a git repo for your queries and S3 location for you results.
95
138
 
96
139
  Advanced setup and configuration details (including how to use Aleph roles for data access, using different auth providers, creating users, and more) can be found [here](docs/ADVANCED_CONFIGURATION.md).
97
140
 
141
+ ## Limitation
142
+ The default maximum result size from Snowflake queries is 5 GB. This is due to the MAX_FILE_SIZE limit of [Snowflake copy command](https://docs.snowflake.net/manuals/sql-reference/sql/copy-into-location.html#copy-options-copyoptions). If Snowflake has changed the limit, update the setting in [snowflake.yml](docs/ADVANCED_CONFIGURATION.md#snowflake)
143
+
98
144
  ## Contribute
99
145
  Aleph is Rails on the backend, Angular on the front end. It uses Resque workers to run queries against Redshift. Here are few things you should have before developing:
100
146
 
@@ -103,7 +149,7 @@ Aleph is Rails on the backend, Angular on the front end. It uses Resque workers
103
149
  * Git Repo (for query versions)
104
150
  * S3 Location (store results)
105
151
 
106
- While the demo/playground version does not use a git repo or S3, we *highly* recommend that you use them in general.
152
+ While the demo/playground version does not use a git repo and S3 is optional for Redshift, we *highly* recommend that you use them in general.
107
153
 
108
154
  ### Setup
109
155
  *Postgres*
@@ -124,6 +170,7 @@ While the demo/playground version does not use a git repo or S3, we *highly* rec
124
170
 
125
171
  ### Testing
126
172
 
173
+ export PATH="$PWD/node_modules/karma-cli/bin:$PATH"
127
174
  RAILS_ENV=test bundle exec rspec spec
128
175
  bundle exec rake karma:run
129
176
 
@@ -135,6 +182,8 @@ You can manage your env variables in a .env file
135
182
  ## Links
136
183
 
137
184
  - [Feature Notes](docs/FEATURES.md)
185
+ - [Development Notes](docs/DEVELOPMENT_NOTES.md)
186
+ - [Operational Notes](docs/OPERATIONAL_NOTES.md)
138
187
  - [Rubygem](https://rubygems.org/gems/aleph_analytics)
139
188
  - [aleph-user group](https://groups.google.com/forum/#!forum/aleph-user)
140
189
 
@@ -1,6 +1,17 @@
1
1
  class QueryExecution
2
2
  @queue = :query_exec
3
3
  NUM_SAMPLE_ROWS = 100
4
+ SNOWFLAKE_UNLOAD_SQL = <<-EOF
5
+ COPY INTO %{location} FROM (
6
+ %{query}
7
+ )
8
+ FILE_FORMAT = (TYPE = 'csv' FIELD_DELIMITER = ',' RECORD_DELIMITER = '\\n' FIELD_OPTIONALLY_ENCLOSED_BY = '"'
9
+ NULL_IF = ('') COMPRESSION = NONE)
10
+ HEADER = TRUE
11
+ SINGLE = TRUE
12
+ OVERWRITE = TRUE
13
+ MAX_FILE_SIZE = %{max_file_size}
14
+ EOF
4
15
 
5
16
  def self.perform(result_id, role)
6
17
  result = Result.find(result_id)
@@ -14,8 +25,24 @@ class QueryExecution
14
25
  result.mark_running!
15
26
  sample_callback = ->(sample) { result.mark_processing_from_sample(sample) }
16
27
 
17
- connection = RedshiftConnectionPool.instance.get(role)
28
+ connection = AnalyticDBConnectionPool.instance.get(role)
29
+ if connection.is_a? RedshiftPG::Connection
30
+ query_redshift(connection, body, result, sample_callback, csv_service)
31
+ else
32
+ query_snowflake(connection, body, result, sample_callback)
33
+ end
34
+
35
+ rescue => e
36
+ if result && csv_service
37
+ csv_service.clear_tmp_file
38
+ result.mark_failed!(e.message)
39
+ end
40
+ raise
41
+ end
18
42
 
43
+ private
44
+
45
+ def self.query_redshift(connection, body, result, sample_callback, csv_service)
19
46
  connection.reconnect_on_failure do
20
47
  query_stream = PgStream::Stream.new(connection.pg_connection, body)
21
48
  result.headers = query_stream.headers
@@ -24,21 +51,37 @@ class QueryExecution
24
51
  rrrc = result.redis_result_row_count
25
52
 
26
53
  stream_processor = PgStream::Processor.new(query_stream)
27
- stream_processor.register(ResultCsvGenerator.new(result_id, result.headers).callbacks)
54
+ stream_processor.register(ResultCsvGenerator.new(result.id, result.headers).callbacks)
28
55
  stream_processor.register(SampleSkimmer.new(NUM_SAMPLE_ROWS, &sample_callback).callbacks)
29
56
  stream_processor.register(CountPublisher.new(rrrc).callbacks)
30
57
 
31
58
  row_count = stream_processor.execute
32
59
  result.mark_complete_with_count(row_count)
33
60
  end
61
+
34
62
  rescue *RedshiftPG::USER_ERROR_CLASSES => e
35
63
  csv_service.clear_tmp_file
36
64
  result.mark_failed!(e.message)
37
- rescue => e
38
- if result && csv_service
39
- csv_service.clear_tmp_file
40
- result.mark_failed!(e.message)
65
+ end
66
+
67
+ def self.query_snowflake(connection, body, result, sample_callback)
68
+ # unload the query result from snowflake directly into s3
69
+ # then read in the first 100 rows from the file as sample rows
70
+ # Note: snowflake unload currently has a max file size of 5 GB.
71
+ connection.reconnect_on_failure do
72
+ body = body.strip.gsub(/;$/, '')
73
+ location = File.join(connection.unload_target, result.current_result_filename)
74
+ sql = SNOWFLAKE_UNLOAD_SQL % {location: location, query: body, max_file_size: connection.max_file_size}
75
+ row = connection.connection.fetch(sql).first
76
+ row_count = row[:rows_unloaded]
77
+
78
+ headers, samples = CsvSerializer.load_from_s3_file(result.current_result_s3_key, NUM_SAMPLE_ROWS)
79
+
80
+ result.headers = headers
81
+ result.save!
82
+
83
+ sample_callback.call(samples)
84
+ result.mark_complete_with_count(row_count)
41
85
  end
42
- raise
43
86
  end
44
87
  end
@@ -53,6 +53,14 @@ class Result < ActiveRecord::Base
53
53
  end
54
54
  end
55
55
 
56
+ def current_result_filename
57
+ @result_filename ||= CsvHelper::Base.new(id).filename
58
+ end
59
+
60
+ def current_result_s3_key
61
+ @result_key ||= CsvHelper::Aws.new(id).key
62
+ end
63
+
56
64
  private
57
65
 
58
66
  def duration(start_field, end_field)
@@ -67,8 +75,4 @@ class Result < ActiveRecord::Base
67
75
  0
68
76
  end
69
77
  end
70
-
71
- def current_result_s3_key
72
- @result_key ||= CsvHelper::Aws.new(id).key
73
- end
74
78
  end
data/bin/aleph CHANGED
@@ -33,6 +33,10 @@ class CommandParser
33
33
  @options[:worker_processes] = w
34
34
  end
35
35
 
36
+ opts.on('-t', '--db_type DB_TYPE', 'redshift or snowflake. Default is redshift') do |t|
37
+ @options[:db_type] = t
38
+ end
39
+
36
40
  opts.on('-H', '--redshift-host REDSHIFT_HOST', 'Redshift Hostname') do |rhost|
37
41
  @options[:redshift_host] = rhost
38
42
  end
@@ -45,12 +49,40 @@ class CommandParser
45
49
  @options[:redshift_port] = rport
46
50
  end
47
51
 
48
- opts.on('-U', '--redshift-user REDSHIFT_USER', 'Redshift User') do |ruser|
49
- @options[:redshift_user] = ruser
52
+ opts.on('-U', '--db-user DB_USER', 'Redshift or Snowflake User') do |dbuser|
53
+ @options[:db_user] = dbuser
54
+ end
55
+
56
+ opts.on('--redshift-user DB_USER', 'Same as --db-user (for backward compatibility)') do |dbuser|
57
+ @options[:db_user] = dbuser
58
+ end
59
+
60
+ opts.on('-P', '--db-password DB_PASSWORD', 'Redshift or Snowflake Password') do |dbpw|
61
+ @options[:db_password] = dbpw
62
+ end
63
+
64
+ opts.on('--redshift-password DB_PASSWORD', 'Same as --db-password (for backward compatibility)') do |dbpw|
65
+ @options[:db_password] = dbpw
66
+ end
67
+
68
+ opts.on('-S', '---dsn ODBC_DSN', 'Snowflake ODBC DSN') do |dsn|
69
+ @options[:dsn] = dsn
70
+ end
71
+
72
+ opts.on('-L', '---snowflake_unload_target STAGE_OR_LOCATION', 'Snowflake only. Stage or location where result files are unloaded') do |target|
73
+ @options[:snowflake_unload_target] = target
74
+ end
75
+
76
+ opts.on('-R', '---s3_region S3_REGION', 's3 Region') do |region|
77
+ @options[:s3_region] = region
78
+ end
79
+
80
+ opts.on('-B', '---s3_bucket S3_BUCKET', 's3 bucket which result files are unloaded. Required for Snowflake DB') do |bucket|
81
+ @options[:s3_bucket] = bucket
50
82
  end
51
83
 
52
- opts.on('-P', '--redshift-password REDSHIFT_PASSWORD', 'Redshift Password') do |rpw|
53
- @options[:redshift_password] = rpw
84
+ opts.on('-F', '---s3_bucket S3_FOLDER', 's3 folder where result files are unloaded') do |folder|
85
+ @options[:s3_folder] = folder
54
86
  end
55
87
 
56
88
  opts.on('-h', '--help', 'Halp!') do |h|
@@ -22,7 +22,16 @@ module AlephExecutables
22
22
  write_yaml('redshift.yml', redshift_properties, environments: [@rails_env.to_sym])
23
23
  @env_writer.merge(admin_redshift_username: user, admin_redshift_password: password)
24
24
  end
25
-
25
+
26
+ def write_snowflake(dsn, user, password, unload_target)
27
+ snowflake_properties = {
28
+ 'dsn' => dsn,
29
+ 'unload_target' => unload_target
30
+ }
31
+ write_yaml('snowflake.yml', snowflake_properties, environments: [@rails_env.to_sym])
32
+ @env_writer.merge(admin_snowflake_username: user, admin_snowflake_password: password)
33
+ end
34
+
26
35
  def write_envs!
27
36
  @env_writer.write!
28
37
  end
@@ -1,8 +1,9 @@
1
1
  module AlephExecutables
2
2
  class Playground
3
- def self.setup(host, db, port, user, password, options = {})
4
- config_path = options[:config_path] || '/tmp/aleph/demo/configuration'
3
+ CONFIG_OPTIONS = [:s3_region, :s3_bucket, :s3_folder]
5
4
 
5
+ def self.setup(db_type, host, dsn, db, port, user, password, options = {})
6
+ config_path = options[:config_path] || '/tmp/aleph/demo/configuration'
6
7
  seed_db = options[:seed_db]
7
8
 
8
9
  config_generator = ConfigGenerator.new(config_path, 'playground')
@@ -10,9 +11,18 @@ module AlephExecutables
10
11
  config_generator.merge_envs(redis_url: 'redis://localhost:6379')
11
12
  config_generator.merge_envs(aleph_query_exec_worker_pool: 1)
12
13
  config_generator.merge_envs(aleph_alert_exec_worker_pool: 1)
13
- properties = { 'auth_type' => 'disabled' }
14
+ config_generator.merge_envs(analytic_db_type: db_type)
15
+
16
+ properties = options.select{ |k,_| CONFIG_OPTIONS.include?(k) }.map{ |k, v| [k.to_s, v] }.to_h.
17
+ merge({ 'auth_type' => 'disabled' })
14
18
  config_generator.write_yaml('config.yml', properties, environments: [:playground])
15
- config_generator.write_redshift(host, db, port, user, password)
19
+
20
+ if db_type == 'snowflake'
21
+ config_generator.write_snowflake(dsn, user, password, options[:snowflake_unload_target])
22
+ else
23
+ config_generator.write_redshift(host, db, port, user, password)
24
+ end
25
+
16
26
  config_generator.write_envs!
17
27
 
18
28
  Bundler.with_clean_env do
@@ -12,7 +12,7 @@ module AlephExecutables
12
12
 
13
13
  def execute!
14
14
  options = @options.select{ |k,v| k == :config_path}.merge(seed_db: true)
15
- Playground.setup(HOST, DB, PORT, USER, PASSWORD, options)
15
+ Playground.setup('redshift', HOST, nil, DB, PORT, USER, PASSWORD, options)
16
16
  end
17
17
  end
18
18
  end
@@ -6,20 +6,32 @@ module AlephExecutables
6
6
  end
7
7
 
8
8
  def execute!
9
- options = @options.select{ |k,v| k == :config_path}
9
+ options = @options.select{ |k,v| [:config_path, :s3_region, :s3_bucket, :s3_folder, :snowflake_unload_target].include?(k) }
10
10
  host = @options[:redshift_host]
11
11
  db = @options[:redshift_db]
12
12
  port = @options[:redshift_port]
13
- user = @options[:redshift_user]
14
- password = @options[:redshift_password]
13
+ user = @options[:db_user]
14
+ password = @options[:db_password]
15
+ dsn = @options[:dsn]
16
+ db_type = @options[:db_type] || 'redshift'
17
+ snowflake_unload_target = @options[:snowflake_unload_target]
18
+ s3_bucket = @options[:s3_bucket]
15
19
 
16
- Utils.fail "Missing Redshift Host", @banner unless present? host
17
- Utils.fail "Missing Redshift Db", @banner unless present? db
18
- Utils.fail "Missing Redshift Port", @banner unless present? port
19
- Utils.fail "Missing Redshift User", @banner unless present? user
20
- Utils.fail "Missing Redshift Password", @banner unless present? password
20
+ Utils.fail "Invalid database type (must be redshift or snowflake)", @banner unless ['redshift', 'snowflake'].include?(db_type)
21
+ Utils.fail "Missing DB User", @banner unless present? user
22
+ Utils.fail "Missing DB Password", @banner unless present? password
21
23
 
22
- Playground.setup host, db, port, user, password, options
24
+ if db_type == 'redshift'
25
+ Utils.fail "Missing Redshift Host", @banner unless present? host
26
+ Utils.fail "Missing Redshift Db", @banner unless present? db
27
+ Utils.fail "Missing Redshift Port", @banner unless present? port
28
+ else
29
+ Utils.fail "Missing Snowflake ODBC DSN", @banner unless present? dsn
30
+ Utils.fail "Missing Snowflake Unload Target", @banner unless present? snowflake_unload_target
31
+ Utils.fail "Missing s3 bucket (This is required for Snowflake connection)", @banner unless present? s3_bucket
32
+ end
33
+
34
+ Playground.setup db_type, host, dsn, db, port, user, password, options
23
35
  end
24
36
 
25
37
  def present?(v)