sequel-snowflake 2.0.0 → 2.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/.github/workflows/gem-push.yml +3 -3
- data/.github/workflows/ruby.yml +6 -4
- data/CHANGELOG.md +14 -4
- data/README.md +3 -3
- data/lib/sequel/adapters/shared/snowflake.rb +32 -0
- data/lib/sequel/adapters/snowflake.rb +10 -0
- data/lib/sequel-snowflake/version.rb +1 -1
- data/sequel-snowflake.gemspec +3 -2
- data/spec/sequel/adapters/snowflake_spec.rb +71 -2
- metadata +9 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 772b801f7ed529ccadccd14d02fad21713a6e62d1d23a6b531647a4a876d5238
|
4
|
+
data.tar.gz: 9b92e7bceb1899f346d117299e733b4773bf65b3b17140968b286ac262026a1e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bd4c7cdf415e197569747c1181056312b3f4389049b3de254ebd407c1e8d882e3cac9f6fe7a5351e6e1330d57abb89e2805fac4a51112049863af189660e7025
|
7
|
+
data.tar.gz: 9d21e394346317988787eadf729d14a0a7caab19fddf639b9b1c9e9227766025c246e15f55b5e44ea9f4b34cc49eac387696ca3835d327a7e69ba34f34e539fa
|
@@ -14,10 +14,10 @@ jobs:
|
|
14
14
|
|
15
15
|
steps:
|
16
16
|
- uses: actions/checkout@v2
|
17
|
-
- name: Set up Ruby
|
18
|
-
uses:
|
17
|
+
- name: Set up Ruby 3.1
|
18
|
+
uses: ruby/setup-ruby@v1
|
19
19
|
with:
|
20
|
-
ruby-version:
|
20
|
+
ruby-version: 3.1
|
21
21
|
|
22
22
|
- name: Publish to RubyGems
|
23
23
|
run: |
|
data/.github/workflows/ruby.yml
CHANGED
@@ -19,16 +19,18 @@ jobs:
|
|
19
19
|
runs-on: ubuntu-latest
|
20
20
|
strategy:
|
21
21
|
matrix:
|
22
|
-
ruby-version: ['
|
22
|
+
ruby-version: ['3.0', '3.1']
|
23
23
|
|
24
24
|
steps:
|
25
25
|
- uses: actions/checkout@v2
|
26
|
-
- name:
|
27
|
-
run: sudo apt-get
|
26
|
+
- name: Update package lists
|
27
|
+
run: sudo apt-get update
|
28
|
+
- name: Install unixodbc-dev, odbcinst, and unixodbc
|
29
|
+
run: sudo apt-get -y install unixodbc-dev odbcinst unixodbc
|
28
30
|
- name: Install Snowflake ODBC driver
|
29
31
|
run: curl ${SNOWFLAKE_DRIVER_URL} -o snowflake_driver.deb && sudo dpkg -i snowflake_driver.deb
|
30
32
|
env:
|
31
|
-
SNOWFLAKE_DRIVER_URL: https://sfc-repo.snowflakecomputing.com/odbc/linux/
|
33
|
+
SNOWFLAKE_DRIVER_URL: https://sfc-repo.snowflakecomputing.com/odbc/linux/3.1.1/snowflake-odbc-3.1.1.x86_64.deb
|
32
34
|
- name: Set up Ruby
|
33
35
|
uses: ruby/setup-ruby@v1
|
34
36
|
with:
|
data/CHANGELOG.md
CHANGED
@@ -1,11 +1,21 @@
|
|
1
|
-
|
1
|
+
# Changelog
|
2
|
+
All notable changes to this project will be documented in this file.
|
2
3
|
|
3
|
-
|
4
|
-
|
4
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
5
|
+
and this project adheres to [Semantic Versioning](http://semver.org/).
|
6
|
+
|
7
|
+
## 2.2.0 / 2023-10-17
|
8
|
+
* Add support for `MERGE` (credit: @benalavi)
|
9
|
+
* Add requirement for `sequel` v5.58.0 or newer (to support the new MERGE methods).
|
5
10
|
|
11
|
+
## 2.1.0 / 2022-06-17
|
12
|
+
* Add support for `EXPLAIN`.
|
6
13
|
|
7
|
-
|
14
|
+
## 2.0.0 / 2021-06-16
|
15
|
+
* Change LICENSE to MIT (open source).
|
16
|
+
* This gem is now tested against Rubies 2.6, 2.7, and 3.0.
|
8
17
|
|
18
|
+
## 1.0.0 / 2021-04-22 [Initial Release]
|
9
19
|
* Handle parsing Snowflake values for the following types:
|
10
20
|
* Numeric data types
|
11
21
|
* String data types
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
An adapter to connect to Snowflake databases using [Sequel](http://sequel.jeremyevans.net/).
|
4
4
|
This provides proper types for returned values, as opposed to the ODBC adapter.
|
5
5
|
|
6
|
-
[](https://github.com/vendasta/sequel-snowflake/actions/workflows/ruby.yml)
|
7
7
|
|
8
8
|
## Installation
|
9
9
|
|
@@ -57,7 +57,7 @@ be taken down either via the `after(:each)` blocks or when the connection is clo
|
|
57
57
|
|
58
58
|
We have two workflows included in this project:
|
59
59
|
|
60
|
-
* Ruby (`ruby.yml`): This runs the specs for this gem against Ruby
|
60
|
+
* Ruby (`ruby.yml`): This runs the specs for this gem against Ruby 3.0 and 3.1. Note
|
61
61
|
that this requires the secret `SNOWFLAKE_CONN_STR` to be set (see above for example connection string),
|
62
62
|
as we need to connect to Snowflake to run tests. These specs will be run for every pull request,
|
63
63
|
and is run after every commit to those branches.
|
@@ -68,7 +68,7 @@ to authenticate with RubyGems.
|
|
68
68
|
|
69
69
|
## Contributing
|
70
70
|
|
71
|
-
1. Fork it ( https://github.com/
|
71
|
+
1. Fork it ( https://github.com/vendasta/sequel-snowflake/fork )
|
72
72
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
73
73
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
74
74
|
4. Push to the branch (`git push origin my-new-feature`)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Sequel
|
2
|
+
module Snowflake
|
3
|
+
Sequel::Database.set_shared_adapter_scheme(:snowflake, self)
|
4
|
+
|
5
|
+
module DatasetMethods
|
6
|
+
# Return an array of strings specifying a query explanation for a SELECT of the
|
7
|
+
# current dataset.
|
8
|
+
# The options (symbolized, in lowercase) are:
|
9
|
+
# JSON: JSON output is easier to store in a table and query.
|
10
|
+
# TABULAR (default): tabular output is generally more human-readable than JSON output.
|
11
|
+
# TEXT: formatted text output is generally more human-readable than JSON output.
|
12
|
+
def explain(opts=OPTS)
|
13
|
+
# Load the PrettyTable class, needed for explain output
|
14
|
+
Sequel.extension(:_pretty_table) unless defined?(Sequel::PrettyTable)
|
15
|
+
|
16
|
+
explain_with_format = if opts[:tabular]
|
17
|
+
"EXPLAIN USING TABULAR"
|
18
|
+
elsif opts[:json]
|
19
|
+
"EXPLAIN USING JSON"
|
20
|
+
elsif opts[:text]
|
21
|
+
"EXPLAIN USING TEXT"
|
22
|
+
else
|
23
|
+
"EXPLAIN"
|
24
|
+
end
|
25
|
+
|
26
|
+
ds = db.send(:metadata_dataset).clone(:sql=>"#{explain_with_format} #{select_sql}")
|
27
|
+
rows = ds.all
|
28
|
+
Sequel::PrettyTable.string(rows, ds.columns)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'sequel'
|
2
2
|
require 'sequel/adapters/odbc'
|
3
|
+
require_relative 'shared/snowflake'
|
3
4
|
|
4
5
|
# A lightweight adapter providing Snowflake support for the `sequel` gem.
|
5
6
|
# The only difference between this and the Sequel-provided ODBC adapter is
|
@@ -20,6 +21,8 @@ module Sequel
|
|
20
21
|
|
21
22
|
# A custom Sequel Dataset class crafted specifically to handle Snowflake results.
|
22
23
|
class Dataset < Sequel::ODBC::Dataset
|
24
|
+
include Sequel::Snowflake::DatasetMethods
|
25
|
+
|
23
26
|
def fetch_rows(sql)
|
24
27
|
execute(sql) do |s|
|
25
28
|
i = -1
|
@@ -35,6 +38,13 @@ module Sequel
|
|
35
38
|
self
|
36
39
|
end
|
37
40
|
|
41
|
+
# Whether the MERGE statement is supported:
|
42
|
+
# https://github.com/jeremyevans/sequel/blob/master/lib/sequel/dataset/features.rb#L129
|
43
|
+
# Snowflake reference: https://docs.snowflake.com/en/sql-reference/sql/merge
|
44
|
+
def supports_merge?
|
45
|
+
true
|
46
|
+
end
|
47
|
+
|
38
48
|
# This is similar to the ODBC adapter's Dataset#convert_odbc_value, except for some special casing
|
39
49
|
# around Snowflake numerics, which come in through ODBC as Strings instead of Numbers.
|
40
50
|
# In those cases, we need to examine the column type as well as the scale,
|
data/sequel-snowflake.gemspec
CHANGED
@@ -8,9 +8,10 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = Sequel::Snowflake::VERSION
|
9
9
|
spec.authors = ["Yesware, Inc"]
|
10
10
|
spec.email = ["engineering@yesware.com"]
|
11
|
+
spec.license = "MIT"
|
11
12
|
spec.summary = %q{Sequel adapter for Snowflake}
|
12
13
|
spec.description = spec.summary
|
13
|
-
spec.homepage = "https://github.com/
|
14
|
+
spec.homepage = "https://github.com/vendasta/sequel-snowflake"
|
14
15
|
|
15
16
|
spec.files = `git ls-files -z`.split("\x0")
|
16
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
@@ -18,7 +19,7 @@ Gem::Specification.new do |spec|
|
|
18
19
|
spec.require_paths = ["lib"]
|
19
20
|
|
20
21
|
|
21
|
-
spec.add_runtime_dependency 'sequel'
|
22
|
+
spec.add_runtime_dependency 'sequel', '>= 5.58.0'
|
22
23
|
spec.add_runtime_dependency 'ruby-odbc'
|
23
24
|
|
24
25
|
spec.add_development_dependency 'rake'
|
@@ -1,10 +1,11 @@
|
|
1
1
|
require 'securerandom'
|
2
2
|
|
3
3
|
describe Sequel::Snowflake::Dataset do
|
4
|
+
let(:db) { Sequel.connect(adapter: :snowflake, drvconnect: ENV['SNOWFLAKE_CONN_STR']) }
|
5
|
+
|
4
6
|
describe 'Converting Snowflake data types' do
|
5
7
|
# Create a test table with a reasonably-random suffix
|
6
|
-
let
|
7
|
-
let!(:db) { Sequel.connect(adapter: :snowflake, drvconnect: ENV['SNOWFLAKE_CONN_STR']) }
|
8
|
+
let(:test_table) { "SEQUEL_SNOWFLAKE_SPECS_#{SecureRandom.hex(10)}".to_sym }
|
8
9
|
|
9
10
|
before(:each) do
|
10
11
|
# Set timezone for parsing timestamps. This gives us a consistent timezone to test against below.
|
@@ -68,4 +69,72 @@ describe Sequel::Snowflake::Dataset do
|
|
68
69
|
expect(db[test_table].select(:n).all).to eq([{ n: 17 }, { n: 18 }])
|
69
70
|
end
|
70
71
|
end
|
72
|
+
|
73
|
+
describe 'MERGE feature' do
|
74
|
+
let(:target_table) { "SEQUEL_SNOWFLAKE_SPECS_#{SecureRandom.hex(10)}".to_sym }
|
75
|
+
let(:source_table) { "SEQUEL_SNOWFLAKE_SPECS_#{SecureRandom.hex(10)}".to_sym }
|
76
|
+
|
77
|
+
before(:each) do
|
78
|
+
db.create_table(target_table, :temp => true) do
|
79
|
+
String :str
|
80
|
+
String :str2
|
81
|
+
String :str3
|
82
|
+
end
|
83
|
+
|
84
|
+
db.create_table(source_table, :temp => true) do
|
85
|
+
String :from
|
86
|
+
String :to
|
87
|
+
String :whomst
|
88
|
+
end
|
89
|
+
|
90
|
+
db[target_table].insert({ str: 'foo', str2: 'foo', str3: 'phoo' })
|
91
|
+
db[target_table].insert({ str: 'baz', str2: 'foo', str3: 'buzz' })
|
92
|
+
db[source_table].insert({ from: 'foo', to: 'bar', whomst: 'me' })
|
93
|
+
end
|
94
|
+
|
95
|
+
after(:each) do
|
96
|
+
db.drop_table(target_table)
|
97
|
+
db.drop_table(source_table)
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'can use MERGE' do
|
101
|
+
db[target_table].merge_using(source_table, str: :from).merge_update(str2: :to).merge
|
102
|
+
|
103
|
+
expect(db[target_table].select_all.all).to match_array([
|
104
|
+
{ str: 'foo', str2: 'bar', str3: 'phoo' },
|
105
|
+
{ str: 'baz', str2: 'foo', str3: 'buzz' }
|
106
|
+
])
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe '#explain' do
|
111
|
+
# Create a test table with a reasonably-random suffix
|
112
|
+
let(:test_table) { "SEQUEL_SNOWFLAKE_SPECS_#{SecureRandom.hex(10)}".to_sym }
|
113
|
+
|
114
|
+
before(:each) do
|
115
|
+
db.create_table(test_table, :temp => true) do
|
116
|
+
Numeric :id
|
117
|
+
String :name
|
118
|
+
String :email
|
119
|
+
String :title
|
120
|
+
end
|
121
|
+
|
122
|
+
db[test_table].insert(
|
123
|
+
{ id: 1, name: 'John Null', email: 'j.null@example.com', title: 'Software Tester' }
|
124
|
+
)
|
125
|
+
end
|
126
|
+
|
127
|
+
after(:each) do
|
128
|
+
db.drop_table(test_table)
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should have explain output" do
|
132
|
+
query = db.fetch("SELECT * FROM #{test_table} WHERE ID=1;")
|
133
|
+
|
134
|
+
expect(query.explain).to be_a_kind_of(String)
|
135
|
+
expect(query.explain(:tabular=>true)).to be_a_kind_of(String)
|
136
|
+
expect(query.explain(:json=>true)).to be_a_kind_of(String)
|
137
|
+
expect(query.explain(:text=>true)).to be_a_kind_of(String)
|
138
|
+
end
|
139
|
+
end
|
71
140
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequel-snowflake
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yesware, Inc
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-10-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sequel
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 5.58.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 5.58.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: ruby-odbc
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,13 +98,15 @@ files:
|
|
98
98
|
- Rakefile
|
99
99
|
- lib/sequel-snowflake.rb
|
100
100
|
- lib/sequel-snowflake/version.rb
|
101
|
+
- lib/sequel/adapters/shared/snowflake.rb
|
101
102
|
- lib/sequel/adapters/snowflake.rb
|
102
103
|
- sequel-snowflake.gemspec
|
103
104
|
- spec/sequel/adapters/snowflake_spec.rb
|
104
105
|
- spec/snowflake_spec.rb
|
105
106
|
- spec/spec_helper.rb
|
106
|
-
homepage: https://github.com/
|
107
|
-
licenses:
|
107
|
+
homepage: https://github.com/vendasta/sequel-snowflake
|
108
|
+
licenses:
|
109
|
+
- MIT
|
108
110
|
metadata: {}
|
109
111
|
post_install_message:
|
110
112
|
rdoc_options: []
|
@@ -121,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
121
123
|
- !ruby/object:Gem::Version
|
122
124
|
version: '0'
|
123
125
|
requirements: []
|
124
|
-
rubygems_version: 3.
|
126
|
+
rubygems_version: 3.3.26
|
125
127
|
signing_key:
|
126
128
|
specification_version: 4
|
127
129
|
summary: Sequel adapter for Snowflake
|