dwh 0.6.0 → 0.6.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ec16e1365da69bdc1778ff349775274d8b3a6d85978a9a69be0d6aa0da44d866
4
- data.tar.gz: 4fc4ed0d62f7e657f80779265fec1945317cbdbd127e43c654916f2f0c157f88
3
+ metadata.gz: 6bfaf112cbfb915c0adc5d504514b6a634b666a97305e55ecbe89b71367fc784
4
+ data.tar.gz: 4e997a453cbff2e904b174b6872944c1a22612e69774a79fde835ea680f5f307
5
5
  SHA512:
6
- metadata.gz: '008e23f7a38eae74baffc20f04b14daf6344dc5e3b9ae8616926fa74fe4bab393b4a21134755dcfc289e999ec967c2c5a2baa98044834ce1f415d6d179046ab4'
7
- data.tar.gz: 2febcb2fb010b298d70b2e010dc1d2be942f63bacc4ef7e57eaf63e5fb616c27472037687ad144c706478ce80be66a7445f9479d9e774f78683ca9d6a9dc3732
6
+ metadata.gz: 649345383a23acece4522e778866b3c9f8ab7c4d5de76101bbca63a701ef71367336e58e7636831e350e58afbee6b59cbd95009a46ddabbb287d46b86129ebf8
7
+ data.tar.gz: 8be2519f016034f9796eeeec261ee9ba0ae56b2cbfe040260c02e817a5fe6ff74baba9b8de05d5aecf6543594ac4471dae9ee5202a169f2d95accec1f57186c6
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.6.2] - 2026-09-30
4
+
5
+ ### Added
6
+
7
+ - **BigQuery**: `client_email` and `private_key` config accept the service-account keyfile's fields inline, so a server can connect without the JSON file on disk. `keyfile` and Application Default Credentials keep working.
8
+
9
+ ## [0.6.1] - 2026-09-30
10
+
11
+ ### Fixed
12
+
13
+ - **BigQuery**: `quote` replaces characters BigQuery rejects in column names (parentheses and similar) so planner-generated aliases such as `Month(Post Date)` execute.
14
+
3
15
  ## [0.6.0] - 2026-09-28
4
16
 
5
17
  ### Added
data/README.md CHANGED
@@ -153,4 +153,4 @@ This project is available as open source under the terms of the MIT License.
153
153
 
154
154
  ## Version
155
155
 
156
- Current version: 0.6.0
156
+ Current version: 0.6.2
@@ -705,12 +705,14 @@ Requires the `google-cloud-bigquery` gem (`gem install google-cloud-bigquery`, p
705
705
  bq = DWH.create(:bigquery, {
706
706
  project_id: 'my-gcp-project',
707
707
  dataset: 'analytics', # default dataset for unqualified table names
708
- keyfile: '/path/to/service-account.json', # optional; omit to use Application Default Credentials
708
+ keyfile: '/path/to/service-account.json', # optional; or pass the keyfile's fields inline:
709
+ # client_email: 'svc@my-gcp-project.iam.gserviceaccount.com',
710
+ # private_key: "-----BEGIN PRIVATE KEY-----\n...",
709
711
  query_timeout: 300 # optional, seconds
710
712
  })
711
713
  ```
712
714
 
713
- Without `keyfile`, credentials resolve via `GOOGLE_APPLICATION_CREDENTIALS` or `gcloud auth application-default login`.
715
+ `client_email` + `private_key` (the two fields the keyfile holds) let a server connect without the file on disk and take precedence over `keyfile`. Without either, credentials resolve via `GOOGLE_APPLICATION_CREDENTIALS` or `gcloud auth application-default login`.
714
716
  Extra client options can be passed with `extra_connection_params` (see `Google::Cloud::Bigquery.new`).
715
717
 
716
718
  ## Configuration Validation
@@ -13,6 +13,14 @@ module DWH
13
13
  # keyfile: '/path/to/service-account.json'
14
14
  # })
15
15
  #
16
+ # @example Inline service-account credentials (the keyfile's client_email and private_key)
17
+ # DWH.create(:bigquery, {
18
+ # project_id: 'my-gcp-project',
19
+ # dataset: 'analytics',
20
+ # client_email: 'svc@my-gcp-project.iam.gserviceaccount.com',
21
+ # private_key: "-----BEGIN PRIVATE KEY-----\n..."
22
+ # })
23
+ #
16
24
  # @example Application Default Credentials (gcloud auth application-default login)
17
25
  # DWH.create(:bigquery, { project_id: 'my-gcp-project', dataset: 'analytics' })
18
26
  class BigQuery < Adapter
@@ -20,19 +28,35 @@ module DWH
20
28
  config :dataset, String, required: true, message: 'default dataset for unqualified table names'
21
29
  config :keyfile, String, required: false, default: nil,
22
30
  message: 'path to service-account JSON; omit to use Application Default Credentials'
31
+ config :client_email, String, required: false, default: nil,
32
+ message: 'service-account email from the keyfile; use with private_key instead of keyfile'
33
+ config :private_key, String, required: false, default: nil,
34
+ message: 'service-account private key (PEM) from the keyfile; use with client_email'
23
35
  config :query_timeout, Integer, required: false, default: 300, message: 'query timeout in seconds'
24
36
 
25
37
  # The schema API reports legacy type names; map the ones whose
26
38
  # normalized type would otherwise be wrong (INTEGER is 64-bit in BigQuery).
27
39
  TYPE_ALIASES = { 'INTEGER' => 'INT64', 'FLOAT' => 'FLOAT64', 'BOOLEAN' => 'BOOL', 'RECORD' => 'STRUCT' }.freeze
28
40
 
41
+ # BigQuery column names, and therefore SELECT aliases, may not contain these
42
+ # characters (https://cloud.google.com/bigquery/docs/schemas#column_names).
43
+ # Dots are left alone so backtick-quoted `dataset.table` paths still work.
44
+ INVALID_NAME_CHARS = %r{[!"$()*,/;?@\[\\\]^{}~]}
45
+
46
+ # (see Functions#quote) Replaces characters BigQuery rejects in a column
47
+ # name so planner-generated aliases like "Month(Post Date)" execute.
48
+ def quote(exp)
49
+ super(exp.to_s.gsub(INVALID_NAME_CHARS, '_'))
50
+ end
51
+
29
52
  # (see Adapter#connection)
30
53
  def connection
31
54
  return @connection if @connection
32
55
 
33
56
  require 'google/cloud/bigquery'
34
57
  opts = { project_id: config[:project_id] }
35
- opts[:credentials] = config[:keyfile] unless config[:keyfile].to_s.empty?
58
+ creds = google_credentials
59
+ opts[:credentials] = creds if creds
36
60
  @connection = Google::Cloud::Bigquery.new(**opts, **extra_connection_params)
37
61
  rescue LoadError
38
62
  raise ConfigError, <<~MSG
@@ -131,6 +155,17 @@ module DWH
131
155
 
132
156
  private
133
157
 
158
+ # Inline service-account fields win over a keyfile path. Neither present
159
+ # means Application Default Credentials.
160
+ def google_credentials
161
+ if config[:client_email].to_s != '' && config[:private_key].to_s != ''
162
+ { 'type' => 'service_account', 'project_id' => config[:project_id],
163
+ 'client_email' => config[:client_email], 'private_key' => config[:private_key] }
164
+ elsif config[:keyfile].to_s != ''
165
+ config[:keyfile]
166
+ end
167
+ end
168
+
134
169
  def dataset_name(qualifiers)
135
170
  qualifiers[:dataset] || qualifiers[:schema] || config[:dataset]
136
171
  end
data/lib/dwh/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DWH
4
- VERSION = '0.6.0'
4
+ VERSION = '0.6.2'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dwh
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ajo Abraham