dwh 0.1.0 → 0.2.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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -0
  3. data/README.md +15 -5
  4. data/Rakefile +1 -1
  5. data/docs/DWH/Adapters/Adapter.html +33 -27
  6. data/docs/DWH/Adapters/Athena.html +25 -21
  7. data/docs/DWH/Adapters/Boolean.html +1 -1
  8. data/docs/DWH/Adapters/Druid.html +18 -12
  9. data/docs/DWH/Adapters/DuckDb.html +29 -27
  10. data/docs/DWH/Adapters/MySql.html +25 -19
  11. data/docs/DWH/Adapters/OpenAuthorizable/ClassMethods.html +3 -6
  12. data/docs/DWH/Adapters/OpenAuthorizable.html +5 -10
  13. data/docs/DWH/Adapters/Postgres.html +27 -23
  14. data/docs/DWH/Adapters/Snowflake.html +39 -24
  15. data/docs/DWH/Adapters/SqlServer.html +27 -25
  16. data/docs/DWH/Adapters/Trino.html +30 -30
  17. data/docs/DWH/Adapters.html +1 -1
  18. data/docs/DWH/AuthenticationError.html +1 -1
  19. data/docs/DWH/Behaviors.html +6 -11
  20. data/docs/DWH/Capabilities.html +10 -26
  21. data/docs/DWH/Column.html +7 -15
  22. data/docs/DWH/ConfigError.html +1 -1
  23. data/docs/DWH/ConnectionError.html +1 -1
  24. data/docs/DWH/DWHError.html +1 -1
  25. data/docs/DWH/ExecutionError.html +1 -1
  26. data/docs/DWH/Factory.html +1 -1
  27. data/docs/DWH/Functions/Arrays.html +8 -8
  28. data/docs/DWH/Functions/Dates.html +5 -7
  29. data/docs/DWH/Functions/ExtractDatePart.html +13 -25
  30. data/docs/DWH/Functions/Nulls.html +3 -3
  31. data/docs/DWH/Functions.html +6 -9
  32. data/docs/DWH/Logger.html +3 -5
  33. data/docs/DWH/OAuthError.html +1 -1
  34. data/docs/DWH/Settings.html +6 -9
  35. data/docs/DWH/StreamingStats.html +2 -3
  36. data/docs/DWH/Table.html +14 -26
  37. data/docs/DWH/TableStats.html +1 -1
  38. data/docs/DWH/TokenExpiredError.html +1 -1
  39. data/docs/DWH/UnsupportedCapability.html +1 -1
  40. data/docs/DWH.html +1 -1
  41. data/docs/_index.html +1 -1
  42. data/docs/file.README.html +43 -48
  43. data/docs/file.adapters.html +318 -343
  44. data/docs/file.creating-adapters.html +347 -357
  45. data/docs/file.getting-started.html +143 -151
  46. data/docs/file.usage.html +257 -278
  47. data/docs/guides/adapters.md +158 -0
  48. data/docs/guides/getting-started.md +6 -1
  49. data/docs/guides/usage.md +33 -1
  50. data/docs/index.html +43 -48
  51. data/docs/top-level-namespace.html +1 -1
  52. data/lib/dwh/adapters/duck_db.rb +1 -1
  53. data/lib/dwh/adapters/postgres.rb +4 -4
  54. data/lib/dwh/adapters/redshift.rb +48 -0
  55. data/lib/dwh/adapters/sql_server.rb +1 -1
  56. data/lib/dwh/adapters/sqlite.rb +364 -0
  57. data/lib/dwh/adapters.rb +5 -5
  58. data/lib/dwh/column.rb +12 -1
  59. data/lib/dwh/functions/dates.rb +15 -0
  60. data/lib/dwh/settings/databricks.yml +13 -13
  61. data/lib/dwh/settings/druid.yml +3 -3
  62. data/lib/dwh/settings/duckdb.yml +2 -2
  63. data/lib/dwh/settings/mysql.yml +2 -2
  64. data/lib/dwh/settings/postgres.yml +11 -11
  65. data/lib/dwh/settings/redshift.yml +15 -24
  66. data/lib/dwh/settings/snowflake.yml +15 -15
  67. data/lib/dwh/settings/sqlite.yml +42 -0
  68. data/lib/dwh/settings.rb +6 -2
  69. data/lib/dwh/table.rb +18 -10
  70. data/lib/dwh/version.rb +1 -1
  71. data/lib/dwh.rb +4 -4
  72. metadata +5 -16
@@ -70,6 +70,71 @@ postgres = DWH.create(:postgres, {
70
70
  })
71
71
  ```
72
72
 
73
+ ## Redshift Adapter
74
+
75
+ The Redshift adapter uses the `pg` gem and provides full-featured RDBMS support.
76
+
77
+ ### Basic Configuration
78
+
79
+ ```ruby
80
+ redshift = DWH.create(:redshift, {
81
+ host: 'localhost',
82
+ port: 5432, # Default: 5432
83
+ database: 'mydb',
84
+ schema: 'public', # Default: 'public'
85
+ username: 'user',
86
+ password: 'password',
87
+ client_name: 'My Application' # Default: 'DWH Ruby Gem'
88
+ })
89
+ ```
90
+
91
+ ### SSL Configuration
92
+
93
+ ```ruby
94
+ # Basic SSL
95
+ redshift = DWH.create(:redshift, {
96
+ host: 'localhost',
97
+ database: 'mydb',
98
+ username: 'user',
99
+ password: 'password',
100
+ ssl: true,
101
+ extra_connection_params: {
102
+ sslmode: 'require' # disable, prefer, require, verify-ca, verify-full
103
+ }
104
+ })
105
+
106
+ # Certificate-based SSL
107
+ redshift = DWH.create(:postgres, {
108
+ host: 'localhost',
109
+ database: 'mydb',
110
+ username: 'user',
111
+ ssl: true,
112
+ extra_connection_params: {
113
+ sslmode: 'verify-full',
114
+ sslrootcert: '/path/to/ca-cert.pem',
115
+ sslcert: '/path/to/client-cert.pem',
116
+ sslkey: '/path/to/client-key.pem'
117
+ }
118
+ })
119
+ ```
120
+
121
+ ### Advanced Configuration
122
+
123
+ ```ruby
124
+ redshift = DWH.create(:redshift, {
125
+ host: 'localhost',
126
+ database: 'mydb',
127
+ username: 'user',
128
+ password: 'password',
129
+ query_timeout: 3600, # seconds, default: 3600
130
+ extra_connection_params: {
131
+ application_name: 'Data Analysis Tool',
132
+ connect_timeout: 10,
133
+ options: '-c maintenance_work_mem=256MB'
134
+ }
135
+ })
136
+ ```
137
+
73
138
  ## Snowflake
74
139
 
75
140
  Snowflake adapter use the REST apis (https) to connect and query. This adapter also supports Multi-Database
@@ -287,6 +352,99 @@ duckdb = DWH.create(:duckdb, {
287
352
  })
288
353
  ```
289
354
 
355
+ ## SQLite Adapter
356
+
357
+ The SQLite adapter uses the `sqlite3` gem for lightweight embedded database analytics. It's optimized for analytical workloads with WAL mode enabled by default for better concurrent read performance.
358
+
359
+ ### Basic Configuration
360
+
361
+ ```ruby
362
+ # File-based database
363
+ sqlite = DWH.create(:sqlite, {
364
+ file: '/path/to/my/database.sqlite'
365
+ })
366
+
367
+ # In-memory database
368
+ sqlite = DWH.create(:sqlite, {
369
+ file: ':memory:'
370
+ })
371
+ ```
372
+
373
+ ### Read-Only Mode
374
+
375
+ ```ruby
376
+ sqlite = DWH.create(:sqlite, {
377
+ file: '/path/to/readonly/database.sqlite',
378
+ readonly: true
379
+ })
380
+ ```
381
+
382
+ ### Performance Optimization
383
+
384
+ The adapter includes default optimizations for analytical workloads:
385
+ - WAL mode enabled by default for concurrent reads
386
+ - 64MB cache size
387
+ - Memory-mapped I/O (128MB)
388
+ - Temp tables stored in memory
389
+
390
+ ```ruby
391
+ # Customize performance settings
392
+ sqlite = DWH.create(:sqlite, {
393
+ file: '/path/to/my/database.sqlite',
394
+ timeout: 5000, # busy timeout in milliseconds, default: 5000
395
+ pragmas: {
396
+ cache_size: -128000, # 128MB cache (negative means KB)
397
+ mmap_size: 268435456, # 256MB memory-mapped I/O
398
+ temp_store: 'MEMORY', # Store temp tables in memory
399
+ synchronous: 'NORMAL' # Faster than FULL, safe with WAL
400
+ }
401
+ })
402
+ ```
403
+
404
+ ### Disable WAL Mode
405
+
406
+ ```ruby
407
+ # Disable WAL mode if needed (e.g., for NFS or network filesystems)
408
+ sqlite = DWH.create(:sqlite, {
409
+ file: '/path/to/my/database.sqlite',
410
+ enable_wal: false
411
+ })
412
+ ```
413
+
414
+ ### Advanced Configuration
415
+
416
+ ```ruby
417
+ sqlite = DWH.create(:sqlite, {
418
+ file: '/path/to/analytics.sqlite',
419
+ readonly: false,
420
+ enable_wal: true, # Default: true
421
+ timeout: 10000, # 10 second busy timeout
422
+ pragmas: {
423
+ journal_mode: 'WAL', # Explicitly set WAL (done by default)
424
+ cache_size: -256000, # 256MB cache
425
+ page_size: 8192, # Larger page size for analytics
426
+ mmap_size: 536870912, # 512MB memory-mapped I/O
427
+ temp_store: 'MEMORY', # Keep temp data in memory
428
+ synchronous: 'NORMAL', # Balance between safety and speed
429
+ locking_mode: 'NORMAL' # Allow multiple connections
430
+ }
431
+ })
432
+ ```
433
+
434
+ ### Multiple Connections
435
+
436
+ Unlike DuckDB, SQLite allows multiple independent connections to the same database file:
437
+
438
+ ```ruby
439
+ # Multiple readers/writers to the same file
440
+ reader = DWH.create(:sqlite, { file: '/path/to/data.sqlite', readonly: true })
441
+ writer = DWH.create(:sqlite, { file: '/path/to/data.sqlite' })
442
+
443
+ # Both can operate concurrently with WAL mode enabled
444
+ data = reader.execute('SELECT * FROM sales')
445
+ writer.execute('INSERT INTO sales VALUES (...)')
446
+ ```
447
+
290
448
  ## Trino Adapter
291
449
 
292
450
  The Trino adapter requires the `trino-client-ruby` gem and works with both Trino and Presto.
@@ -40,9 +40,14 @@ postgres = DWH.create(:postgres, {
40
40
  password: 'password'
41
41
  })
42
42
 
43
+ # Connect to SQLite (lightweight, embedded)
44
+ sqlite = DWH.create(:sqlite, {
45
+ file: '/path/to/analytics.db'
46
+ })
47
+
43
48
  # Connect to DuckDB (in-memory)
44
49
  duckdb = DWH.create(:duckdb, {
45
- database: ':memory:'
50
+ file: ':memory:'
46
51
  })
47
52
  ```
48
53
 
data/docs/guides/usage.md CHANGED
@@ -293,7 +293,7 @@ native = adapter.execute(sql, format: :native) # Database's native format
293
293
  # Use streaming for large result sets
294
294
  def export_large_table(adapter, table_name, output_file)
295
295
  query = "SELECT * FROM #{table_name}"
296
-
296
+
297
297
  File.open(output_file, 'w') do |file|
298
298
  adapter.execute_stream(query, file)
299
299
  end
@@ -309,6 +309,38 @@ def process_large_dataset(adapter, query)
309
309
  end
310
310
  ```
311
311
 
312
+ ### SQLite Performance Tuning
313
+
314
+ SQLite adapter comes with optimized defaults for analytical workloads, but can be further tuned:
315
+
316
+ ```ruby
317
+ # High-performance SQLite configuration for analytics
318
+ sqlite = DWH.create(:sqlite, {
319
+ file: '/path/to/large_analytics.db',
320
+ enable_wal: true, # WAL mode for concurrent reads (default: true)
321
+ timeout: 30000, # 30 second busy timeout for heavy writes
322
+ pragmas: {
323
+ cache_size: -512000, # 512MB cache for large datasets
324
+ page_size: 8192, # Larger pages for sequential scans
325
+ mmap_size: 1073741824, # 1GB memory-mapped I/O
326
+ temp_store: 'MEMORY', # Keep temp tables in RAM
327
+ synchronous: 'NORMAL', # Balance safety/speed (safe with WAL)
328
+ journal_size_limit: 67108864 # 64MB journal limit
329
+ }
330
+ })
331
+
332
+ # Read-only analytics queries with maximum performance
333
+ readonly_analytics = DWH.create(:sqlite, {
334
+ file: '/path/to/data.db',
335
+ readonly: true, # Read-only for maximum concurrency
336
+ pragmas: {
337
+ cache_size: -256000, # 256MB cache
338
+ mmap_size: 2147483648, # 2GB memory mapping for large files
339
+ temp_store: 'MEMORY' # Fast temp operations
340
+ }
341
+ })
342
+ ```
343
+
312
344
  ## Error Handling and Debugging
313
345
 
314
346
  ### Comprehensive Error Handling
data/docs/index.html CHANGED
@@ -57,15 +57,14 @@
57
57
  <div class="clear"></div>
58
58
  </div>
59
59
 
60
- <div id="content"><div id='filecontents'>
61
- <p><a href="https://github.com/stratasite/dwh/actions"><img src="https://github.com/stratasite/dwh/workflows/Ruby/badge.svg" alt="Ruby" /></a></p>
60
+ <div id="content"><div id='filecontents'><p><a href="https://github.com/stratasite/dwh/actions"><img src="https://github.com/stratasite/dwh/workflows/Ruby/badge.svg" alt="Ruby"></a></p>
62
61
 
63
- <h1 id="dwh---data-warehouse-adapter-library">DWH - Data Warehouse Adapter Library</h1>
62
+ <h1 id="dwh-data-warehouse-adapter-library">DWH - Data Warehouse Adapter Library</h1>
64
63
 
65
64
  <p>A light weight library to connect, introspect, and query popular databases over a unified interface. This gem is intended for analtyical workloads. The library also provides database specific translations for common functions like <code>date_trunc</code>, <code>date_add</code> etc. The function tranlation is not comprehensive. But, it does provides good coverage for date handling, and some array handling as well.</p>
66
65
 
67
66
  <blockquote>
68
- <p>[!NOTE]
67
+ <p>[!NOTE]
69
68
  <strong>This is not an ORM</strong> nor will it cast types to ruby unless the underlying client does it out of the box. The goal here is to create an Architecture where new databases can be onboarded quickly.</p>
70
69
  </blockquote>
71
70
 
@@ -78,57 +77,55 @@
78
77
  <h2 id="features">Features</h2>
79
78
 
80
79
  <ul>
81
- <li><strong>Unified Interface</strong>: Connect to multiple database types using the same API</li>
82
- <li><strong>SQL Function Translation</strong>: Automatically translates common SQL functions to database-specific syntax</li>
83
- <li><strong>Connection Pooling</strong>: Built-in connection pool management for high-performance applications</li>
84
- <li><strong>Rich Metadata</strong>: Extract table schemas, column information, and statistics</li>
80
+ <li><strong>Unified Interface</strong>: Connect to multiple database types using the same API</li>
81
+ <li><strong>SQL Function Translation</strong>: Automatically translates common SQL functions to database-specific syntax</li>
82
+ <li><strong>Connection Pooling</strong>: Built-in connection pool management for high-performance applications</li>
83
+ <li><strong>Rich Metadata</strong>: Extract table schemas, column information, and statistics</li>
85
84
  </ul>
86
85
 
87
86
  <h2 id="supported-databases">Supported Databases</h2>
88
87
 
89
88
  <ul>
90
- <li><strong>Snowflake</strong> - High performance cloud warehouse</li>
91
- <li><strong>Trino</strong> (formerly Presto) - Distributed SQL query engine</li>
92
- <li><strong>AWS Athena</strong> - AWS big data warehouse</li>
93
- <li><strong>Apache Druid</strong> - Real-time analytics database</li>
94
- <li><strong>DuckDB</strong> - In-process analytical database</li>
95
- <li><strong>PostgreSQL</strong> - Full-featured RDBMS with advanced SQL support</li>
96
- <li><strong>MySQL</strong> - Popular open-source database</li>
97
- <li><strong>SQL Server</strong> - Microsofts enterprise database</li>
89
+ <li><strong>Snowflake</strong> - High performance cloud warehouse</li>
90
+ <li><strong>Trino</strong> (formerly Presto) - Distributed SQL query engine</li>
91
+ <li><strong>AWS Athena</strong> - AWS big data warehouse</li>
92
+ <li><strong>Apache Druid</strong> - Real-time analytics database</li>
93
+ <li><strong>DuckDB</strong> - In-process analytical database</li>
94
+ <li><strong>PostgreSQL</strong> - Full-featured RDBMS with advanced SQL support</li>
95
+ <li><strong>MySQL</strong> - Popular open-source database</li>
96
+ <li><strong>SQL Server</strong> - Microsoft&#39;s enterprise database</li>
98
97
  </ul>
99
98
 
100
99
  <h2 id="integrations-coming-soon">Integrations Coming Soon</h2>
101
100
 
102
101
  <ul>
103
- <li><strong>Redshift</strong> - AWS data warehouse platform</li>
104
- <li><strong>ClickHouse</strong> - High performance analytical db</li>
105
- <li><strong>Databricks</strong> - Big data compute engine</li>
106
- <li><strong>MotherDuck</strong> - Hosted DuckDB service</li>
102
+ <li><strong>Redshift</strong> - AWS data warehouse platform</li>
103
+ <li><strong>ClickHouse</strong> - High performance analytical db</li>
104
+ <li><strong>Databricks</strong> - Big data compute engine</li>
105
+ <li><strong>MotherDuck</strong> - Hosted DuckDB service</li>
107
106
  </ul>
108
107
 
109
108
  <h2 id="quick-start">Quick Start</h2>
110
109
 
111
110
  <p>Install it yourself as:</p>
112
111
 
113
- <p><code>bash
114
- gem install dwh
115
- </code></p>
112
+ <pre class="code bash"><code class="bash">gem install dwh
113
+ </code></pre>
116
114
 
117
115
  <h3 id="connect-and-execute-a-basic-query">Connect and Execute a Basic Query</h3>
118
116
 
119
- <p>```ruby
120
- require ‘dwh’</p>
117
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>dwh</span><span class='tstring_end'>&#39;</span></span>
121
118
 
122
- <h1 id="connect-to-druid">Connect to Druid</h1>
123
- <p>druid = DWH.create(:druid, {
124
- host: localhost’,
125
- port: 8080,
126
- protocol: http
127
- })</p>
119
+ <span class='comment'># Connect to Druid
120
+ </span><span class='id identifier rubyid_druid'>druid</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="DWH.html" title="DWH (module)">DWH</a></span></span><span class='period'>.</span><span class='id identifier rubyid_create'><span class='object_link'><a href="DWH/Factory.html#create-instance_method" title="DWH::Factory#create (method)">create</a></span></span><span class='lparen'>(</span><span class='symbol'>:druid</span><span class='comma'>,</span> <span class='lbrace'>{</span>
121
+ <span class='label'>host:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>localhost</span><span class='tstring_end'>&#39;</span></span><span class='comma'>,</span>
122
+ <span class='label'>port:</span> <span class='int'>8080</span><span class='comma'>,</span>
123
+ <span class='label'>protocol:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>http</span><span class='tstring_end'>&#39;</span></span>
124
+ <span class='rbrace'>}</span><span class='rparen'>)</span>
128
125
 
129
- <h1 id="basic-query-execution">basic query execution</h1>
130
- <p>results = druid.execute(SELECT * FROM web_sales”, format: :csv)
131
- ```</p>
126
+ <span class='comment'># basic query execution
127
+ </span><span class='id identifier rubyid_results'>results</span> <span class='op'>=</span> <span class='id identifier rubyid_druid'>druid</span><span class='period'>.</span><span class='id identifier rubyid_execute'>execute</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>SELECT * FROM web_sales</span><span class='tstring_end'>&quot;</span></span><span class='comma'>,</span> <span class='label'>format:</span> <span class='symbol'>:csv</span><span class='rparen'>)</span>
128
+ </code></pre>
132
129
 
133
130
  <h2 id="core-api">Core API</h2>
134
131
 
@@ -152,10 +149,11 @@ require ‘dwh’</p>
152
149
  <h2 id="tutorials-and-guides">Tutorials and Guides</h2>
153
150
 
154
151
  <ul>
155
- <li><a href="/docs/guides/getting-started.md">Getting Started</a></li>
156
- <li><a href="/docs/guides/adapters.md">Adapter Configuration</a></li>
157
- <li><a href="/docs/guides/creating-adapters.md">Creating an Adapter</a></li>
158
- <li><a href="https://rubydoc.info/github/stratasite/dwh.git">API</a></li>
152
+ <li><a href="https://strata.site/dwh/file.getting-started.html">Getting Started</a></li>
153
+ <li><a href="https://strata.site/dwh/file.adapters.html">Adapter Configuration</a></li>
154
+ <li><a href="https://strata.site/dwh/file.creating-adapters.html">Creating an Adapter</a></li>
155
+ <li><a href="https://strata.site/dwh/file.usage.html">Advanced Usage</a></li>
156
+ <li><a href="https://strata.site/dwh/DWH.html">API</a></li>
159
157
  </ul>
160
158
 
161
159
  <h2 id="testing">Testing</h2>
@@ -164,21 +162,18 @@ require ‘dwh’</p>
164
162
 
165
163
  <p>Run Unit Tests:</p>
166
164
 
167
- <p><code>bash
168
- bundle exec rake test:unit
169
- </code></p>
165
+ <pre class="code bash"><code class="bash">bundle exec rake test:unit
166
+ </code></pre>
170
167
 
171
168
  <p>Run tests on RDBMS dbs:</p>
172
169
 
173
- <p><code>bash
174
- bundle exec rake test:system:rdbms
175
- </code></p>
170
+ <pre class="code bash"><code class="bash">bundle exec rake test:system:rdbms
171
+ </code></pre>
176
172
 
177
173
  <p>Run tests on druid:</p>
178
174
 
179
- <p><code>bash
180
- bundle exec rake test:system:druid
181
- </code></p>
175
+ <pre class="code bash"><code class="bash">bundle exec rake test:system:druid
176
+ </code></pre>
182
177
 
183
178
  <h2 id="development">Development</h2>
184
179
 
@@ -200,7 +195,7 @@ bundle exec rake test:system:druid
200
195
  </div></div>
201
196
 
202
197
  <div id="footer">
203
- Generated on Fri Aug 22 08:31:21 2025 by
198
+ Generated on Mon Aug 25 10:59:27 2025 by
204
199
  <a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
205
200
  0.9.37 (ruby-3.4.4).
206
201
  </div>
@@ -100,7 +100,7 @@
100
100
  </div>
101
101
 
102
102
  <div id="footer">
103
- Generated on Fri Aug 22 08:31:21 2025 by
103
+ Generated on Mon Aug 25 10:59:27 2025 by
104
104
  <a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
105
105
  0.9.37 (ruby-3.4.4).
106
106
  </div>
@@ -150,7 +150,7 @@ module DWH
150
150
 
151
151
  # True if the configuration was setup with a schema.
152
152
  def schema?
153
- config[:schema].present?
153
+ !config[:schema].nil? && !config[:schema]&.strip&.empty?
154
154
  end
155
155
 
156
156
  # (see Adapter#execute)
@@ -27,7 +27,7 @@ module DWH
27
27
  config :schema, String, default: 'public', message: 'schema name. defaults to "public"'
28
28
  config :username, String, required: true, message: 'connection username'
29
29
  config :password, String, required: false, default: nil, message: 'connection password'
30
- config :query_timeout, String, required: false, default: 3600, message: 'query execution timeout in seconds'
30
+ config :query_timeout, Integer, required: false, default: 3600, message: 'query execution timeout in seconds'
31
31
  config :ssl, Boolean, required: false, default: false, message: 'use ssl'
32
32
  config :client_name, String, required: false, default: 'DWH Ruby Gem', message: 'The name of the connecting app'
33
33
 
@@ -45,7 +45,7 @@ module DWH
45
45
  password: config[:password],
46
46
  application_name: config[:client_name]
47
47
  }.merge(extra_connection_params)
48
- properties[:options] = "#{properties[:options]} -c statement_timeout=#{config[:query_timeout]}s"
48
+ properties[:options] = "#{properties[:options]} -c statement_timeout=#{config[:query_timeout] * 1000}"
49
49
 
50
50
  @connection = PG.connect(properties)
51
51
 
@@ -114,7 +114,7 @@ module DWH
114
114
  db_table = Table.new table, schema: qualifiers[:schema]
115
115
 
116
116
  schema_where = ''
117
- if db_table.schema.present?
117
+ if db_table.schema?
118
118
  schema_where = "AND table_schema = '#{db_table.schema}'"
119
119
  elsif schema?
120
120
  schema_where = "AND table_schema in (#{qualified_schema_name})"
@@ -143,7 +143,7 @@ module DWH
143
143
 
144
144
  # True if the configuration was setup with a schema.
145
145
  def schema?
146
- config[:schema].present?
146
+ !config[:schema].nil? && !config[:schema]&.strip&.empty?
147
147
  end
148
148
 
149
149
  # (see Adapter#execute)
@@ -0,0 +1,48 @@
1
+ module DWH
2
+ module Adapters
3
+ # Redshift adapter. Please ensure the pg gem is available before using this adapter.
4
+ # Generally, adapters should be created using {DWH::Factory#create DWH.create}. Where a configuration
5
+ # is passed in as options hash or argument list.
6
+ #
7
+ # @example Basic connection with required only options
8
+ # DWH.create(:redshift, {host: 'localhost', database: 'redshift',
9
+ # username: 'redshift'})
10
+ #
11
+ # @example Connection with cert based SSL connection
12
+ # DWH.create(:redshift, {host: 'localhost', database: 'redshift',
13
+ # username: 'redshift', ssl: true,
14
+ # extra_connection_params: { sslmode: 'require' })
15
+ #
16
+ # valid sslmodes: disable, prefer, require, verify-ca, verify-full
17
+ # For modes requiring Certs make sure you add the appropirate params
18
+ # to extra_connection_params. (ie sslrootcert, sslcert etc.)
19
+ #
20
+ # @example Connection sending custom application name
21
+ # DWH.create(:redshift, {host: 'localhost', database: 'redshift',
22
+ # username: 'redshift', application_name: "Strata CLI" })
23
+ class Redshift < Postgres
24
+ config :host, String, required: true, message: 'server host ip address or domain name'
25
+ config :port, Integer, required: false, default: 5439, message: 'port to connect to'
26
+ config :database, String, required: true, message: 'name of database to connect to'
27
+ config :schema, String, default: 'public', message: 'schema name. defaults to "public"'
28
+ config :username, String, required: true, message: 'connection username'
29
+ config :password, String, required: false, default: nil, message: 'connection password'
30
+ config :query_timeout, Integer, required: false, default: 3600, message: 'query execution timeout in seconds'
31
+ config :client_name, String, required: false, default: 'DWH Ruby Gem', message: 'The name of the connecting app'
32
+ config :ssl, Boolean, required: false, default: false, message: 'use ssl'
33
+
34
+ # Need to override default add method
35
+ # since redshift doesn't support quarter as an
36
+ # interval.
37
+ # @param unit [String] Should be one of day, month, quarter etc
38
+ # @param val [String, Integer] The number of days to add
39
+ # @param exp [String] The sql expresssion to modify
40
+ def date_add(unit, val, exp)
41
+ gsk(:date_add)
42
+ .gsub(/@unit/i, unit)
43
+ .gsub(/@val/i, val.to_s)
44
+ .gsub(/@exp/i, exp)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -142,7 +142,7 @@ module DWH
142
142
  change_current_database(db_table.catalog)
143
143
 
144
144
  schema_where = ''
145
- schema_where = "AND table_schema = '#{db_table.schema}'" if db_table.schema.present?
145
+ schema_where = "AND table_schema = '#{db_table.schema}'" if db_table.schema?
146
146
 
147
147
  sql = <<-SQL
148
148
  SELECT column_name, data_type, character_maximum_length, numeric_precision,numeric_scale