olaf 0.3.0 → 1.0.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/README.md +5 -8
- data/lib/olaf/query_definition/class_methods.rb +7 -7
- data/lib/olaf/query_definition.rb +2 -2
- data/lib/olaf.rb +7 -8
- data/olaf.gemspec +2 -4
- data/test/olaf_configure_test.rb +14 -14
- data/test/olaf_execute_test.rb +2 -2
- data/test/olaf_lazy_loading_test.rb +2 -4
- metadata +2 -17
- data/lib/olaf/drivers/snowflake.rb +0 -28
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9d45d092623bf97e4a23624cfcc145afd281dcb91011bee43e9086e35f1af9ff
|
|
4
|
+
data.tar.gz: 54ae40103a4ed018b04be956f86ad9316a2239ab719e721e33eb9d79a11e1b2c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f874ca55bef0c740c90084a7db2e0487668a55c4af33e6d8879c798677aa4921eb0aa1c1f146d0af54c2de854b61c783c0a70e362b31c2cc5baf8cbee8ab37d4
|
|
7
|
+
data.tar.gz: 97331d8aa92d9b735b45c7931a08bccc49db2e97caee1ab11c1b0f19c067b63192a29625c356a90d5d85eee8f1f59ed924c4712d71ba5bbfbe581a058a911cc2
|
data/README.md
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# Olaf
|
|
2
2
|
|
|
3
|
-
Olaf is a small Ruby wrapper for warehouse queries, running them in
|
|
4
|
-
in BigQuery.
|
|
3
|
+
Olaf is a small Ruby wrapper for warehouse queries, running them in BigQuery.
|
|
5
4
|
|
|
6
5
|

|
|
7
6
|
|
|
@@ -13,7 +12,6 @@ and only when it is used, so add to your `Gemfile` the ones you configure:
|
|
|
13
12
|
|
|
14
13
|
| Driver | Gems | Also needs |
|
|
15
14
|
| ----------------- | ----------------------- | ----------------------- |
|
|
16
|
-
| `Olaf::Snowflake` | `sequel`, `ruby-odbc` | the ODBC system library |
|
|
17
15
|
| `Olaf::BigQuery` | `google-cloud-bigquery` | |
|
|
18
16
|
| `Olaf::Fake` | — | |
|
|
19
17
|
|
|
@@ -34,7 +32,7 @@ control in the code and in tests.
|
|
|
34
32
|
class FetchUsers
|
|
35
33
|
include Olaf::QueryDefinition
|
|
36
34
|
|
|
37
|
-
template './
|
|
35
|
+
template './big_query/users_in_department.sql'
|
|
38
36
|
|
|
39
37
|
argument :department_id
|
|
40
38
|
|
|
@@ -52,7 +50,6 @@ Olaf.execute(query)
|
|
|
52
50
|
One driver, which every query runs on:
|
|
53
51
|
|
|
54
52
|
```ruby
|
|
55
|
-
Olaf.configure(user: 'olaf') # Olaf::Snowflake, the default
|
|
56
53
|
Olaf.configure(olaf_driver: Olaf::Fake) # ideal for testing
|
|
57
54
|
```
|
|
58
55
|
|
|
@@ -62,10 +59,10 @@ run on the `default:`, the first one given when it is not specified:
|
|
|
62
59
|
```ruby
|
|
63
60
|
Olaf.configure(
|
|
64
61
|
drivers: {
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
big_query: Olaf::BigQuery.new(project: 'carwow', labels: { service: 'flatmin' }),
|
|
63
|
+
fake: Olaf::Fake.new
|
|
67
64
|
},
|
|
68
|
-
default: :
|
|
65
|
+
default: :big_query
|
|
69
66
|
)
|
|
70
67
|
|
|
71
68
|
class FetchUsers
|
|
@@ -3,7 +3,7 @@ module Olaf
|
|
|
3
3
|
module ClassMethods
|
|
4
4
|
# Creates a new instance of the Query defined and validates
|
|
5
5
|
# the parameters passed, leaving the instance in a ready-to-execute state.
|
|
6
|
-
# @return
|
|
6
|
+
# @return Olaf::QueryDefinition instance
|
|
7
7
|
def prepare(**vars)
|
|
8
8
|
new(**vars).prepare
|
|
9
9
|
end
|
|
@@ -15,9 +15,9 @@ module Olaf
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
# Define an argument for the query matching a placeholder in the template.
|
|
18
|
-
# The
|
|
19
|
-
#
|
|
20
|
-
#
|
|
18
|
+
# The driver binds the value passed as a query parameter. Sometimes, we need
|
|
19
|
+
# to pass an argument as literal to substitute it into the SQL instead
|
|
20
|
+
# (i.e. sending a table_name)
|
|
21
21
|
#
|
|
22
22
|
# options - Hash config for each argument
|
|
23
23
|
# :as - Argument Type
|
|
@@ -26,7 +26,7 @@ module Olaf
|
|
|
26
26
|
# Example:
|
|
27
27
|
#
|
|
28
28
|
# class OneQuery
|
|
29
|
-
# include
|
|
29
|
+
# include Olaf::QueryDefinition
|
|
30
30
|
#
|
|
31
31
|
# template 'reports/one.sql'
|
|
32
32
|
#
|
|
@@ -48,7 +48,7 @@ module Olaf
|
|
|
48
48
|
# Example:
|
|
49
49
|
#
|
|
50
50
|
# class OneQuery
|
|
51
|
-
# include
|
|
51
|
+
# include Olaf::QueryDefinition
|
|
52
52
|
#
|
|
53
53
|
# template 'reports/one.sql'
|
|
54
54
|
# end
|
|
@@ -93,7 +93,7 @@ module Olaf
|
|
|
93
93
|
# Example:
|
|
94
94
|
#
|
|
95
95
|
# class OneQuery
|
|
96
|
-
# include
|
|
96
|
+
# include Olaf::QueryDefinition
|
|
97
97
|
#
|
|
98
98
|
# row_object MyOwnObject
|
|
99
99
|
# end
|
|
@@ -20,8 +20,8 @@ module Olaf
|
|
|
20
20
|
#
|
|
21
21
|
# @return QueryDefinition instance
|
|
22
22
|
#
|
|
23
|
-
# @raises
|
|
24
|
-
# @raises
|
|
23
|
+
# @raises Olaf::UndefinedArgumentsError
|
|
24
|
+
# @raises Olaf::MissingArgumentsError
|
|
25
25
|
def prepare
|
|
26
26
|
@sql_template ||= File.read(self.class.template)
|
|
27
27
|
|
data/lib/olaf.rb
CHANGED
|
@@ -5,21 +5,19 @@ module Olaf
|
|
|
5
5
|
# Autoloaded: each driver pulls in its own client library.
|
|
6
6
|
autoload :BigQuery, File.expand_path('olaf/drivers/big_query', __dir__)
|
|
7
7
|
autoload :Fake, File.expand_path('olaf/drivers/fake', __dir__)
|
|
8
|
-
autoload :Snowflake, File.expand_path('olaf/drivers/snowflake', __dir__)
|
|
9
8
|
|
|
10
9
|
DEFAULT_DRIVER = :default
|
|
11
10
|
|
|
12
11
|
# Configures the drivers used to execute queries, either a single one built
|
|
13
12
|
# from the arguments given:
|
|
14
13
|
#
|
|
15
|
-
# Olaf.configure(user: 'olaf') # Olaf::Snowflake, the default
|
|
16
14
|
# Olaf.configure(olaf_driver: Olaf::Fake) # ideal for testing
|
|
17
15
|
#
|
|
18
16
|
# or several instantiated ones, which queries pick by name with `driver`:
|
|
19
17
|
#
|
|
20
18
|
# Olaf.configure(
|
|
21
|
-
# drivers: {
|
|
22
|
-
# default: :
|
|
19
|
+
# drivers: { big_query: Olaf::BigQuery.new(project: 'carwow'), fake: Olaf::Fake.new },
|
|
20
|
+
# default: :big_query
|
|
23
21
|
# )
|
|
24
22
|
#
|
|
25
23
|
# @return the default Olaf driver instance
|
|
@@ -36,7 +34,9 @@ module Olaf
|
|
|
36
34
|
|
|
37
35
|
[drivers.dup, default_driver]
|
|
38
36
|
else
|
|
39
|
-
|
|
37
|
+
raise ArgumentError, 'Pass `drivers:` or a single `olaf_driver:` to configure' unless olaf_driver
|
|
38
|
+
|
|
39
|
+
[{ DEFAULT_DRIVER => olaf_driver.new(**args) }, DEFAULT_DRIVER]
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
instance
|
|
@@ -64,9 +64,8 @@ module Olaf
|
|
|
64
64
|
# what keeps `Olaf::Fake` covering every query in tests.
|
|
65
65
|
#
|
|
66
66
|
# @return Olaf driver instance
|
|
67
|
-
# * Olaf::Fake
|
|
68
|
-
# * Olaf::
|
|
69
|
-
# * Olaf::BigQuery - google-cloud-bigquery driver to run queries in BigQuery
|
|
67
|
+
# * Olaf::Fake - Ideal for testing
|
|
68
|
+
# * Olaf::BigQuery - google-cloud-bigquery driver to run queries in BigQuery
|
|
70
69
|
#
|
|
71
70
|
def self.instance(name = nil)
|
|
72
71
|
drivers = @drivers || raise('You need to configure Olaf before using it!')
|
data/olaf.gemspec
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Gem::Specification.new do |s|
|
|
2
2
|
s.name = 'olaf'
|
|
3
|
-
s.version = '0.
|
|
3
|
+
s.version = '1.0.0'
|
|
4
4
|
s.date = Time.now.strftime('%Y-%m-%d')
|
|
5
5
|
s.summary = 'Ruby wrapper for warehouse queries.'
|
|
6
6
|
s.authors = ['Emiliano Mancuso']
|
|
@@ -18,9 +18,7 @@ Gem::Specification.new do |s|
|
|
|
18
18
|
|
|
19
19
|
# Drivers load their own client libraries, so consumers only install the ones
|
|
20
20
|
# they configure:
|
|
21
|
-
# Olaf::
|
|
22
|
-
# Olaf::BigQuery - google-cloud-bigquery
|
|
21
|
+
# Olaf::BigQuery - google-cloud-bigquery
|
|
23
22
|
s.add_development_dependency 'google-cloud-bigquery', '~> 1.64'
|
|
24
|
-
s.add_development_dependency 'sequel', '~> 5.37'
|
|
25
23
|
s.add_development_dependency 'test-unit', '~> 3.3'
|
|
26
24
|
end
|
data/test/olaf_configure_test.rb
CHANGED
|
@@ -20,10 +20,10 @@ class OlafConfigureTest < Test::Unit::TestCase
|
|
|
20
20
|
assert_equal Olaf.instance.config, { other: 'configs', like: 'user and passwd' }
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
def
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
def test_configure_requires_a_driver
|
|
24
|
+
assert_raise ArgumentError do
|
|
25
|
+
Olaf.configure(random: 'stuff')
|
|
26
|
+
end
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def test_configure_returns_the_default_driver
|
|
@@ -31,33 +31,33 @@ class OlafConfigureTest < Test::Unit::TestCase
|
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
def test_configure_registers_several_drivers
|
|
34
|
-
|
|
34
|
+
postgres = MockDriver.new
|
|
35
35
|
big_query = MockDriver.new
|
|
36
36
|
|
|
37
|
-
Olaf.configure(drivers: {
|
|
37
|
+
Olaf.configure(drivers: { postgres: postgres, big_query: big_query }, default: :postgres)
|
|
38
38
|
|
|
39
|
-
assert_equal Olaf.instance,
|
|
40
|
-
assert_equal Olaf.instance(:
|
|
39
|
+
assert_equal Olaf.instance, postgres
|
|
40
|
+
assert_equal Olaf.instance(:postgres), postgres
|
|
41
41
|
assert_equal Olaf.instance(:big_query), big_query
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
def test_configure_defaults_to_the_first_driver_registered
|
|
45
|
-
|
|
45
|
+
postgres = MockDriver.new
|
|
46
46
|
|
|
47
|
-
Olaf.configure(drivers: {
|
|
47
|
+
Olaf.configure(drivers: { postgres: postgres, big_query: MockDriver.new })
|
|
48
48
|
|
|
49
|
-
assert_equal Olaf.instance,
|
|
49
|
+
assert_equal Olaf.instance, postgres
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
def test_configure_rejects_a_default_that_was_not_registered
|
|
53
53
|
assert_raise_message(/Unknown default driver :redshift/) do
|
|
54
|
-
Olaf.configure(drivers: {
|
|
54
|
+
Olaf.configure(drivers: { postgres: MockDriver.new }, default: :redshift)
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
def test_configure_rejects_both_forms_at_once
|
|
59
59
|
assert_raise ArgumentError do
|
|
60
|
-
Olaf.configure(olaf_driver: MockDriver, drivers: {
|
|
60
|
+
Olaf.configure(olaf_driver: MockDriver, drivers: { postgres: MockDriver.new })
|
|
61
61
|
end
|
|
62
62
|
end
|
|
63
63
|
|
|
@@ -74,7 +74,7 @@ class OlafConfigureTest < Test::Unit::TestCase
|
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
def test_instance_raises_for_a_driver_that_was_not_registered
|
|
77
|
-
Olaf.configure(drivers: {
|
|
77
|
+
Olaf.configure(drivers: { postgres: MockDriver.new, big_query: MockDriver.new })
|
|
78
78
|
|
|
79
79
|
assert_raise Olaf::UnknownDriverError do
|
|
80
80
|
Olaf.instance(:redshift)
|
data/test/olaf_execute_test.rb
CHANGED
|
@@ -81,7 +81,7 @@ class OlafExecuteTest < Test::Unit::TestCase
|
|
|
81
81
|
default_driver = RecordingDriver.new
|
|
82
82
|
other_driver = RecordingDriver.new
|
|
83
83
|
|
|
84
|
-
Olaf.configure(drivers: { big_query: other_driver,
|
|
84
|
+
Olaf.configure(drivers: { big_query: other_driver, postgres: default_driver }, default: :postgres)
|
|
85
85
|
|
|
86
86
|
Olaf.execute(@query_instance)
|
|
87
87
|
|
|
@@ -98,7 +98,7 @@ class OlafExecuteTest < Test::Unit::TestCase
|
|
|
98
98
|
end
|
|
99
99
|
|
|
100
100
|
def test_execute_raises_when_the_driver_declared_is_not_configured
|
|
101
|
-
Olaf.configure(drivers: { default: RecordingDriver.new,
|
|
101
|
+
Olaf.configure(drivers: { default: RecordingDriver.new, postgres: RecordingDriver.new })
|
|
102
102
|
|
|
103
103
|
@query.driver :big_query
|
|
104
104
|
|
|
@@ -12,15 +12,13 @@ class OlafLazyLoadingTest < Test::Unit::TestCase
|
|
|
12
12
|
assert_equal loaded_after('require "olaf"; Olaf.configure(olaf_driver: Olaf::Fake)'), []
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
def
|
|
16
|
-
assert_equal loaded_after('require "olaf"; Olaf.configure(
|
|
15
|
+
def test_configuring_the_big_query_driver_loads_its_client_only
|
|
16
|
+
assert_equal loaded_after('require "olaf"; Olaf.configure(olaf_driver: Olaf::BigQuery)'), ['google-cloud-bigquery']
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
private
|
|
20
20
|
|
|
21
21
|
DEPENDENCIES = {
|
|
22
|
-
'sequel' => 'Sequel',
|
|
23
|
-
'odbc_utf8' => 'ODBC',
|
|
24
22
|
'google-cloud-bigquery' => 'Google::Cloud::Bigquery'
|
|
25
23
|
}.freeze
|
|
26
24
|
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: olaf
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Emiliano Mancuso
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-09
|
|
10
|
+
date: 2026-10-09 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: google-cloud-bigquery
|
|
@@ -23,20 +23,6 @@ dependencies:
|
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '1.64'
|
|
26
|
-
- !ruby/object:Gem::Dependency
|
|
27
|
-
name: sequel
|
|
28
|
-
requirement: !ruby/object:Gem::Requirement
|
|
29
|
-
requirements:
|
|
30
|
-
- - "~>"
|
|
31
|
-
- !ruby/object:Gem::Version
|
|
32
|
-
version: '5.37'
|
|
33
|
-
type: :development
|
|
34
|
-
prerelease: false
|
|
35
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
-
requirements:
|
|
37
|
-
- - "~>"
|
|
38
|
-
- !ruby/object:Gem::Version
|
|
39
|
-
version: '5.37'
|
|
40
26
|
- !ruby/object:Gem::Dependency
|
|
41
27
|
name: test-unit
|
|
42
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -62,7 +48,6 @@ files:
|
|
|
62
48
|
- lib/olaf.rb
|
|
63
49
|
- lib/olaf/drivers/big_query.rb
|
|
64
50
|
- lib/olaf/drivers/fake.rb
|
|
65
|
-
- lib/olaf/drivers/snowflake.rb
|
|
66
51
|
- lib/olaf/errors.rb
|
|
67
52
|
- lib/olaf/query_definition.rb
|
|
68
53
|
- lib/olaf/query_definition/class_methods.rb
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
require 'sequel'
|
|
2
|
-
|
|
3
|
-
module Olaf
|
|
4
|
-
class Snowflake
|
|
5
|
-
WRAPPED_ERRORS = [Sequel::DatabaseError].freeze
|
|
6
|
-
|
|
7
|
-
def initialize(**config)
|
|
8
|
-
@config = config
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def fetch(olaf_query)
|
|
12
|
-
conn.fetch(olaf_query.sql_template, **olaf_query.variables).all
|
|
13
|
-
rescue *WRAPPED_ERRORS => error
|
|
14
|
-
raise QueryExecutionError.new(error.message, olaf_query)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
private
|
|
18
|
-
|
|
19
|
-
def conn
|
|
20
|
-
# Only opening a connection needs the ODBC system library.
|
|
21
|
-
@conn ||= begin
|
|
22
|
-
require 'odbc_utf8'
|
|
23
|
-
|
|
24
|
-
Sequel.odbc('snowflake', **@config)
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|