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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -0
- data/README.md +15 -5
- data/Rakefile +1 -1
- data/docs/DWH/Adapters/Adapter.html +33 -27
- data/docs/DWH/Adapters/Athena.html +25 -21
- data/docs/DWH/Adapters/Boolean.html +1 -1
- data/docs/DWH/Adapters/Druid.html +18 -12
- data/docs/DWH/Adapters/DuckDb.html +29 -27
- data/docs/DWH/Adapters/MySql.html +25 -19
- data/docs/DWH/Adapters/OpenAuthorizable/ClassMethods.html +3 -6
- data/docs/DWH/Adapters/OpenAuthorizable.html +5 -10
- data/docs/DWH/Adapters/Postgres.html +27 -23
- data/docs/DWH/Adapters/Snowflake.html +39 -24
- data/docs/DWH/Adapters/SqlServer.html +27 -25
- data/docs/DWH/Adapters/Trino.html +30 -30
- data/docs/DWH/Adapters.html +1 -1
- data/docs/DWH/AuthenticationError.html +1 -1
- data/docs/DWH/Behaviors.html +6 -11
- data/docs/DWH/Capabilities.html +10 -26
- data/docs/DWH/Column.html +7 -15
- data/docs/DWH/ConfigError.html +1 -1
- data/docs/DWH/ConnectionError.html +1 -1
- data/docs/DWH/DWHError.html +1 -1
- data/docs/DWH/ExecutionError.html +1 -1
- data/docs/DWH/Factory.html +1 -1
- data/docs/DWH/Functions/Arrays.html +8 -8
- data/docs/DWH/Functions/Dates.html +5 -7
- data/docs/DWH/Functions/ExtractDatePart.html +13 -25
- data/docs/DWH/Functions/Nulls.html +3 -3
- data/docs/DWH/Functions.html +6 -9
- data/docs/DWH/Logger.html +3 -5
- data/docs/DWH/OAuthError.html +1 -1
- data/docs/DWH/Settings.html +6 -9
- data/docs/DWH/StreamingStats.html +2 -3
- data/docs/DWH/Table.html +14 -26
- data/docs/DWH/TableStats.html +1 -1
- data/docs/DWH/TokenExpiredError.html +1 -1
- data/docs/DWH/UnsupportedCapability.html +1 -1
- data/docs/DWH.html +1 -1
- data/docs/_index.html +1 -1
- data/docs/file.README.html +43 -48
- data/docs/file.adapters.html +318 -343
- data/docs/file.creating-adapters.html +347 -357
- data/docs/file.getting-started.html +143 -151
- data/docs/file.usage.html +257 -278
- data/docs/guides/adapters.md +158 -0
- data/docs/guides/getting-started.md +6 -1
- data/docs/guides/usage.md +33 -1
- data/docs/index.html +43 -48
- data/docs/top-level-namespace.html +1 -1
- data/lib/dwh/adapters/duck_db.rb +1 -1
- data/lib/dwh/adapters/postgres.rb +4 -4
- data/lib/dwh/adapters/redshift.rb +48 -0
- data/lib/dwh/adapters/sql_server.rb +1 -1
- data/lib/dwh/adapters/sqlite.rb +364 -0
- data/lib/dwh/adapters.rb +5 -5
- data/lib/dwh/column.rb +12 -1
- data/lib/dwh/functions/dates.rb +15 -0
- data/lib/dwh/settings/databricks.yml +13 -13
- data/lib/dwh/settings/druid.yml +3 -3
- data/lib/dwh/settings/duckdb.yml +2 -2
- data/lib/dwh/settings/mysql.yml +2 -2
- data/lib/dwh/settings/postgres.yml +11 -11
- data/lib/dwh/settings/redshift.yml +15 -24
- data/lib/dwh/settings/snowflake.yml +15 -15
- data/lib/dwh/settings/sqlite.yml +42 -0
- data/lib/dwh/settings.rb +6 -2
- data/lib/dwh/table.rb +18 -10
- data/lib/dwh/version.rb +1 -1
- data/lib/dwh.rb +4 -4
- metadata +5 -16
data/docs/guides/adapters.md
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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'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
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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
|
-
<
|
|
114
|
-
|
|
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
|
-
<
|
|
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'>'</span><span class='tstring_content'>dwh</span><span class='tstring_end'>'</span></span>
|
|
121
118
|
|
|
122
|
-
<
|
|
123
|
-
|
|
124
|
-
host
|
|
125
|
-
port
|
|
126
|
-
protocol
|
|
127
|
-
})</
|
|
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'>'</span><span class='tstring_content'>localhost</span><span class='tstring_end'>'</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'>'</span><span class='tstring_content'>http</span><span class='tstring_end'>'</span></span>
|
|
124
|
+
<span class='rbrace'>}</span><span class='rparen'>)</span>
|
|
128
125
|
|
|
129
|
-
<
|
|
130
|
-
|
|
131
|
-
|
|
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'>"</span><span class='tstring_content'>SELECT * FROM web_sales</span><span class='tstring_end'>"</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
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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
|
-
<
|
|
168
|
-
|
|
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
|
-
<
|
|
174
|
-
|
|
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
|
-
<
|
|
180
|
-
|
|
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
|
|
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
|
|
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>
|
data/lib/dwh/adapters/duck_db.rb
CHANGED
|
@@ -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,
|
|
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]}
|
|
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
|
|
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].
|
|
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
|
|
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
|