dwh 0.1.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 +7 -0
- data/.rubocop.yml +36 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE +21 -0
- data/README.md +130 -0
- data/Rakefile +42 -0
- data/docs/DWH/Adapters/Adapter.html +3053 -0
- data/docs/DWH/Adapters/Athena.html +1704 -0
- data/docs/DWH/Adapters/Boolean.html +121 -0
- data/docs/DWH/Adapters/Druid.html +1626 -0
- data/docs/DWH/Adapters/DuckDb.html +2012 -0
- data/docs/DWH/Adapters/MySql.html +1704 -0
- data/docs/DWH/Adapters/OpenAuthorizable/ClassMethods.html +265 -0
- data/docs/DWH/Adapters/OpenAuthorizable.html +1102 -0
- data/docs/DWH/Adapters/Postgres.html +2000 -0
- data/docs/DWH/Adapters/Snowflake.html +1662 -0
- data/docs/DWH/Adapters/SqlServer.html +2084 -0
- data/docs/DWH/Adapters/Trino.html +1835 -0
- data/docs/DWH/Adapters.html +129 -0
- data/docs/DWH/AuthenticationError.html +142 -0
- data/docs/DWH/Behaviors.html +767 -0
- data/docs/DWH/Capabilities.html +748 -0
- data/docs/DWH/Column.html +1115 -0
- data/docs/DWH/ConfigError.html +143 -0
- data/docs/DWH/ConnectionError.html +143 -0
- data/docs/DWH/DWHError.html +138 -0
- data/docs/DWH/ExecutionError.html +143 -0
- data/docs/DWH/Factory.html +1133 -0
- data/docs/DWH/Functions/Arrays.html +505 -0
- data/docs/DWH/Functions/Dates.html +1644 -0
- data/docs/DWH/Functions/ExtractDatePart.html +804 -0
- data/docs/DWH/Functions/Nulls.html +377 -0
- data/docs/DWH/Functions.html +846 -0
- data/docs/DWH/Logger.html +258 -0
- data/docs/DWH/OAuthError.html +138 -0
- data/docs/DWH/Settings.html +658 -0
- data/docs/DWH/StreamingStats.html +804 -0
- data/docs/DWH/Table.html +1260 -0
- data/docs/DWH/TableStats.html +583 -0
- data/docs/DWH/TokenExpiredError.html +142 -0
- data/docs/DWH/UnsupportedCapability.html +135 -0
- data/docs/DWH.html +220 -0
- data/docs/_index.html +471 -0
- data/docs/class_list.html +54 -0
- data/docs/css/common.css +1 -0
- data/docs/css/full_list.css +58 -0
- data/docs/css/style.css +503 -0
- data/docs/file.README.html +210 -0
- data/docs/file.adapters.html +514 -0
- data/docs/file.creating-adapters.html +497 -0
- data/docs/file.getting-started.html +288 -0
- data/docs/file.usage.html +446 -0
- data/docs/file_list.html +79 -0
- data/docs/frames.html +22 -0
- data/docs/guides/adapters.md +445 -0
- data/docs/guides/creating-adapters.md +430 -0
- data/docs/guides/getting-started.md +225 -0
- data/docs/guides/usage.md +378 -0
- data/docs/index.html +210 -0
- data/docs/js/app.js +344 -0
- data/docs/js/full_list.js +242 -0
- data/docs/js/jquery.js +4 -0
- data/docs/method_list.html +2038 -0
- data/docs/top-level-namespace.html +110 -0
- data/lib/dwh/adapters/athena.rb +359 -0
- data/lib/dwh/adapters/druid.rb +267 -0
- data/lib/dwh/adapters/duck_db.rb +235 -0
- data/lib/dwh/adapters/my_sql.rb +235 -0
- data/lib/dwh/adapters/open_authorizable.rb +215 -0
- data/lib/dwh/adapters/postgres.rb +250 -0
- data/lib/dwh/adapters/snowflake.rb +489 -0
- data/lib/dwh/adapters/sql_server.rb +257 -0
- data/lib/dwh/adapters/trino.rb +213 -0
- data/lib/dwh/adapters.rb +363 -0
- data/lib/dwh/behaviors.rb +67 -0
- data/lib/dwh/capabilities.rb +39 -0
- data/lib/dwh/column.rb +79 -0
- data/lib/dwh/errors.rb +29 -0
- data/lib/dwh/factory.rb +125 -0
- data/lib/dwh/functions/arrays.rb +42 -0
- data/lib/dwh/functions/dates.rb +162 -0
- data/lib/dwh/functions/extract_date_part.rb +70 -0
- data/lib/dwh/functions/nulls.rb +31 -0
- data/lib/dwh/functions.rb +86 -0
- data/lib/dwh/logger.rb +50 -0
- data/lib/dwh/settings/athena.yml +77 -0
- data/lib/dwh/settings/base.yml +81 -0
- data/lib/dwh/settings/databricks.yml +51 -0
- data/lib/dwh/settings/druid.yml +59 -0
- data/lib/dwh/settings/duckdb.yml +44 -0
- data/lib/dwh/settings/mysql.yml +67 -0
- data/lib/dwh/settings/postgres.yml +30 -0
- data/lib/dwh/settings/redshift.yml +52 -0
- data/lib/dwh/settings/snowflake.yml +45 -0
- data/lib/dwh/settings/sqlserver.yml +80 -0
- data/lib/dwh/settings/trino.yml +77 -0
- data/lib/dwh/settings.rb +79 -0
- data/lib/dwh/streaming_stats.rb +69 -0
- data/lib/dwh/table.rb +105 -0
- data/lib/dwh/table_stats.rb +51 -0
- data/lib/dwh/version.rb +5 -0
- data/lib/dwh.rb +54 -0
- data/sig/dwh.rbs +4 -0
- metadata +231 -0
@@ -0,0 +1,288 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="UTF-8">
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
|
+
<title>
|
7
|
+
File: Getting Started
|
8
|
+
|
9
|
+
— Documentation by YARD 0.9.37
|
10
|
+
|
11
|
+
</title>
|
12
|
+
|
13
|
+
<link rel="stylesheet" href="css/style.css" type="text/css" />
|
14
|
+
|
15
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" />
|
16
|
+
|
17
|
+
<script type="text/javascript">
|
18
|
+
pathId = "getting-started";
|
19
|
+
relpath = '';
|
20
|
+
</script>
|
21
|
+
|
22
|
+
|
23
|
+
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
|
24
|
+
|
25
|
+
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
|
26
|
+
|
27
|
+
|
28
|
+
</head>
|
29
|
+
<body>
|
30
|
+
<div class="nav_wrap">
|
31
|
+
<iframe id="nav" src="file_list.html?1"></iframe>
|
32
|
+
<div id="resizer"></div>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div id="main" tabindex="-1">
|
36
|
+
<div id="header">
|
37
|
+
<div id="menu">
|
38
|
+
|
39
|
+
<a href="_index.html">Index</a> »
|
40
|
+
<span class="title">File: Getting Started</span>
|
41
|
+
|
42
|
+
</div>
|
43
|
+
|
44
|
+
<div id="search">
|
45
|
+
|
46
|
+
<a class="full_list_link" id="class_list_link"
|
47
|
+
href="class_list.html">
|
48
|
+
|
49
|
+
<svg width="24" height="24">
|
50
|
+
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
|
51
|
+
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
|
52
|
+
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
|
53
|
+
</svg>
|
54
|
+
</a>
|
55
|
+
|
56
|
+
</div>
|
57
|
+
<div class="clear"></div>
|
58
|
+
</div>
|
59
|
+
|
60
|
+
<div id="content"><div id='filecontents'><h1 id="getting-started-with-dwh">Getting Started with DWH</h1>
|
61
|
+
|
62
|
+
<p>DWH is a lightweight library that provides a unified interface to connect, introspect, and query popular databases. This guide will help you get up and running quickly.</p>
|
63
|
+
|
64
|
+
<h2 id="installation">Installation</h2>
|
65
|
+
|
66
|
+
<p>Add this line to your application’s Gemfile:</p>
|
67
|
+
|
68
|
+
<p><code>ruby
|
69
|
+
gem 'dwh'
|
70
|
+
</code></p>
|
71
|
+
|
72
|
+
<p>And then execute:</p>
|
73
|
+
|
74
|
+
<p><code>bash
|
75
|
+
bundle install
|
76
|
+
</code></p>
|
77
|
+
|
78
|
+
<p>Or install it yourself as:</p>
|
79
|
+
|
80
|
+
<p><code>bash
|
81
|
+
gem install dwh
|
82
|
+
</code></p>
|
83
|
+
|
84
|
+
<h2 id="basic-usage">Basic Usage</h2>
|
85
|
+
|
86
|
+
<h3 id="creating-your-first-connection">Creating Your First Connection</h3>
|
87
|
+
|
88
|
+
<p>```ruby
|
89
|
+
require ‘dwh’</p>
|
90
|
+
|
91
|
+
<h1 id="connect-to-postgresql">Connect to PostgreSQL</h1>
|
92
|
+
<p>postgres = DWH.create(:postgres, {
|
93
|
+
host: ‘localhost’,
|
94
|
+
database: ‘mydb’,
|
95
|
+
username: ‘user’,
|
96
|
+
password: ‘password’
|
97
|
+
})</p>
|
98
|
+
|
99
|
+
<h1 id="connect-to-duckdb-in-memory">Connect to DuckDB (in-memory)</h1>
|
100
|
+
<p>duckdb = DWH.create(:duckdb, {
|
101
|
+
database: ‘:memory:’
|
102
|
+
})
|
103
|
+
```</p>
|
104
|
+
|
105
|
+
<h3 id="your-first-query">Your First Query</h3>
|
106
|
+
|
107
|
+
<p>```ruby
|
108
|
+
# Execute a simple query
|
109
|
+
results = postgres.execute(“SELECT * FROM users LIMIT 10”)</p>
|
110
|
+
|
111
|
+
<h1 id="results-are-returned-as-arrays-by-default">Results are returned as arrays by default</h1>
|
112
|
+
<p>results.each do |row|
|
113
|
+
puts row.inspect
|
114
|
+
end
|
115
|
+
```</p>
|
116
|
+
|
117
|
+
<h3 id="exploring-your-database">Exploring Your Database</h3>
|
118
|
+
|
119
|
+
<p>```ruby
|
120
|
+
# List all tables
|
121
|
+
tables = postgres.tables
|
122
|
+
puts “Available tables: #tables.map(&:physical_name)”</p>
|
123
|
+
|
124
|
+
<h1 id="get-detailed-information-about-a-table">Get detailed information about a table</h1>
|
125
|
+
<p>table_info = postgres.metadata(‘users’)
|
126
|
+
puts “Table: #table_infotable_info.physical_name”
|
127
|
+
puts “Schema: #table_infotable_info.schema”
|
128
|
+
puts “Columns:”
|
129
|
+
table_info.columns.each do |column|
|
130
|
+
puts “ #columncolumn.name (#columncolumn.normalized_data_type)”
|
131
|
+
end</p>
|
132
|
+
|
133
|
+
<h1 id="get-table-statistics">Get table statistics</h1>
|
134
|
+
<p>stats = postgres.stats(‘users’, date_column: ‘created_at’)
|
135
|
+
puts “Row count: #statsstats.row_count”
|
136
|
+
puts “Date range: #statsstats.date_start to #statsstats.date_end”
|
137
|
+
```</p>
|
138
|
+
|
139
|
+
<h3 id="different-output-formats">Different Output Formats</h3>
|
140
|
+
|
141
|
+
<p>```ruby
|
142
|
+
# Get results as arrays (default)
|
143
|
+
array_results = postgres.execute(“SELECT id, name FROM users LIMIT 5”)</p>
|
144
|
+
|
145
|
+
<h1 id="get-results-as-hashesobjects">Get results as hashes/objects</h1>
|
146
|
+
<p>hash_results = postgres.execute(“SELECT id, name FROM users LIMIT 5”, format: :object)</p>
|
147
|
+
|
148
|
+
<h1 id="get-results-as-csv-string">Get results as CSV string</h1>
|
149
|
+
<p>csv_results = postgres.execute(“SELECT id, name FROM users LIMIT 5”, format: :csv)</p>
|
150
|
+
|
151
|
+
<h1 id="stream-large-results-to-a-file">Stream large results to a file</h1>
|
152
|
+
<p>postgres.execute_stream(“SELECT * FROM large_table”, File.open(‘output.csv’, ‘w’))
|
153
|
+
```</p>
|
154
|
+
|
155
|
+
<h3 id="streaming-large-datasets">Streaming Large Datasets</h3>
|
156
|
+
|
157
|
+
<p>```ruby
|
158
|
+
# stream data while tracting stats and previewing data in a separate thread
|
159
|
+
stats = DWH::StreamingStats.new(10000) # num of rows to keep in memory for previewing
|
160
|
+
exec_thread = Thread.new {
|
161
|
+
postgres.execute_stream(“SELECT * FROM large_table”, File.open(‘output.csv’, ‘w’), stats: stats)
|
162
|
+
}</p>
|
163
|
+
|
164
|
+
<p>mon_thread = Thread.new{
|
165
|
+
loop do
|
166
|
+
break if exec_thread.alive?</p>
|
167
|
+
|
168
|
+
<pre class="code ruby"><code class="ruby">puts stats.data.last end }
|
169
|
+
</code></pre>
|
170
|
+
|
171
|
+
<p>[exec_thread, mon_thread].each(&:join)</p>
|
172
|
+
|
173
|
+
<h1 id="stream-with-block-processing">Stream with block processing</h1>
|
174
|
+
<p>postgres.stream(“SELECT * FROM large_table”) do |chunk|
|
175
|
+
process_chunk(chunk)
|
176
|
+
end</p>
|
177
|
+
|
178
|
+
<p>```</p>
|
179
|
+
|
180
|
+
<h2 id="advanced-usage">Advanced Usage</h2>
|
181
|
+
|
182
|
+
<h3 id="connection-pooling">Connection Pooling</h3>
|
183
|
+
|
184
|
+
<p>```ruby
|
185
|
+
# Create a connection pool
|
186
|
+
pool = DWH.pool(‘my_postgres_pool’, :postgres, {
|
187
|
+
host: ‘localhost’,
|
188
|
+
database: ‘mydb’,
|
189
|
+
username: ‘user’,
|
190
|
+
password: ‘password’
|
191
|
+
}, size: 10, timeout: 5)</p>
|
192
|
+
|
193
|
+
<h1 id="use-the-pool">Use the pool</h1>
|
194
|
+
<p>pool.with do |connection|
|
195
|
+
results = connection.execute(“SELECT COUNT(*) FROM users”)
|
196
|
+
end</p>
|
197
|
+
|
198
|
+
<h1 id="shutdown-the-pool-when-done">Shutdown the pool when done</h1>
|
199
|
+
<p>DWH.shutdown(‘my_postgres_pool’)
|
200
|
+
```</p>
|
201
|
+
|
202
|
+
<h3 id="using-extra-connection-params">Using Extra Connection Params</h3>
|
203
|
+
|
204
|
+
<p>DWH uses an existing Ruby gem where possible to connect to each target database. When that is not possible and the db supports a REST endpoint, we will use Faraday.</p>
|
205
|
+
|
206
|
+
<p>Using <code>extra_connection_params</code> key you can pass in a Hash of options that the target connector supports but DWH doesn’t make first class. The main config options in DWH are based on required and common needs.</p>
|
207
|
+
|
208
|
+
<h4 id="sending-postgres-connecttimeout-property-supported-by-the-pg-gem">Sending Postgres ‘connect_timeout’ property supported by the PG gem</h4>
|
209
|
+
|
210
|
+
<p>```ruby
|
211
|
+
pg = DWH.create(:postgres, {
|
212
|
+
host: ‘localhost’,
|
213
|
+
database: ‘mydb’,
|
214
|
+
username: ‘user’,
|
215
|
+
password: ‘password’,
|
216
|
+
extra_connection_params: {
|
217
|
+
connect_timeout: 5
|
218
|
+
}
|
219
|
+
})</p>
|
220
|
+
|
221
|
+
<p>```</p>
|
222
|
+
|
223
|
+
<h3 id="database-functions">Database Functions</h3>
|
224
|
+
|
225
|
+
<p>DWH provides a function translation layer that converts common SQL functions to database-specific syntax:</p>
|
226
|
+
|
227
|
+
<p>```ruby
|
228
|
+
# Date truncation
|
229
|
+
postgres.truncate_date(‘week’, ‘created_at’) # => DATE_TRUNC(‘week’, created_at)
|
230
|
+
sqlserver.truncate_date(‘week’, ‘created_at’) # => DATETRUNC(week, created_at)</p>
|
231
|
+
|
232
|
+
<h1 id="date-literals">Date literals</h1>
|
233
|
+
<p>postgres.date_literal(‘2025-01-01’) # => ‘2025-01-01’::DATE
|
234
|
+
sqlserver.date_literal(‘2025-01-01’) # => ‘2025-01-01’</p>
|
235
|
+
|
236
|
+
<h1 id="null-handling">Null handling</h1>
|
237
|
+
<p>adapter.coalesce(‘column1’, ‘column2’, “‘default’”) # => COALESCE(column1, column2, ‘default’)
|
238
|
+
adapter.null_if(‘column1’, “‘empty’”) # => NULLIF(column1, ‘empty’)</p>
|
239
|
+
|
240
|
+
<h1 id="string-functions">String functions</h1>
|
241
|
+
<p>adapter.trim(‘column_name’) # => TRIM(column_name)
|
242
|
+
adapter.upper_case(‘column_name’) # => UPPER(column_name)
|
243
|
+
adapter.lower_case(‘column_name’) # => LOWER(column_name)
|
244
|
+
```</p>
|
245
|
+
|
246
|
+
<h2 id="core-api">Core API</h2>
|
247
|
+
|
248
|
+
<p>Standardized API across adapters:</p>
|
249
|
+
|
250
|
+
<dl>
|
251
|
+
<dt>connection</dt>
|
252
|
+
<dd>creates a reusuable connection based on config hash passed in</dd>
|
253
|
+
<dt>tables(schema: nil, catalog: nil)</dt>
|
254
|
+
<dd>returns a list of tables from the default connection or from the specified schema and catalog</dd>
|
255
|
+
<dt>metadata(table_name, schema: nil, catalog: nil)</dt>
|
256
|
+
<dd>provides metadata about a table</dd>
|
257
|
+
<dt>stats(table_name, date_column: nil)</dt>
|
258
|
+
<dd>provides table row count and date range</dd>
|
259
|
+
<dt>execute(sql, format: :array, retries: 0)</dt>
|
260
|
+
<dd>runs a query and returns in given format</dd>
|
261
|
+
<dt>execute_stream(sql, io, stats: nil)</dt>
|
262
|
+
<dd>runs a query and streams it as csv into the given io</dd>
|
263
|
+
</dl>
|
264
|
+
|
265
|
+
<h2 id="error-handling">Error Handling</h2>
|
266
|
+
|
267
|
+
<p><code>ruby
|
268
|
+
begin
|
269
|
+
results = adapter.execute("SELECT * FROM non_existent_table")
|
270
|
+
rescue DWH::ExecutionError => e
|
271
|
+
puts "Query failed: #{e.message}"
|
272
|
+
rescue DWH::ConnectionError => e
|
273
|
+
puts "Connection failed: #{e.message}"
|
274
|
+
rescue DWH::ConfigError => e
|
275
|
+
puts "Configuration error: #{e.message}"
|
276
|
+
end
|
277
|
+
</code></p>
|
278
|
+
</div></div>
|
279
|
+
|
280
|
+
<div id="footer">
|
281
|
+
Generated on Fri Aug 22 08:31:21 2025 by
|
282
|
+
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
283
|
+
0.9.37 (ruby-3.4.4).
|
284
|
+
</div>
|
285
|
+
|
286
|
+
</div>
|
287
|
+
</body>
|
288
|
+
</html>
|