athens 0.2.0 → 0.3.4

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: d1fb8ee7934d4e7019f1f54dbd3b3eb4368536e3974a00b35442898e4e8b267f
4
- data.tar.gz: 1685787b3a1c68f850cc7ca01523a0f3a4feaeaae26ed5d9f77e41ffdafe4b15
3
+ metadata.gz: 763fdc0eeba122974a101d60e8b17045d3d55dcf63f7144fe4db181a6808b858
4
+ data.tar.gz: 2afff645fa2b925e9317100043a2c574574c7245a99edbc29c8da5c508cb766a
5
5
  SHA512:
6
- metadata.gz: 7ba436dc94c82c4b6642e8084e76455d3f32a786bc718364c89f2e3769b3786ddcfb65f0e1526d62b56c5d11a6e6e67cab501f3063b8e5e0c59fa2e46a219292
7
- data.tar.gz: b6ef5c5bd6e318348fb4bb9fb794c37ff57be2e13bdcaaeef707246a524b3ea6b5d65ba62e0a2d3d7dbfab696ac6fbbfbfad33f943c473d1c2abc8747849658d
6
+ metadata.gz: a0e3cf85dfd919a884f90de3bdb1a6896bedc12ed327ae237858ae4182d2565e7d4c19453b2d68f77717ed8763c65ba6565ba654ef34c49aed2273e51d43c5cb
7
+ data.tar.gz: 387787c6e6f2ab20ff30714374591fd7211fbb9b3181e35df0a0e27fe800444af1d7428c00c7648c1ba2e3b7f1a1e6672574f0e3a38cfa1124d1bcaadd83adcd
data/CHANGELOG.md CHANGED
@@ -1,3 +1,25 @@
1
+ ## 0.3.4 / 2021-03-02
2
+
3
+ * Added configurable polling period (thanks [jesseproudman](https://github.com/jesseproudman))
4
+
5
+ ## 0.3.3 / 2021-01-12
6
+
7
+ * Added support for Ruby 3.0 (thanks [blackjiro](https://github.com/blackjiro))
8
+
9
+ ## 0.3.2 / 2020-11-24
10
+
11
+ * Added optional `request_token` and `work_group` parameters to the query execute method (thanks [mediafinger](https://github.com/mediafinger))
12
+
13
+ ## 0.3.1 / 2020-07-20
14
+
15
+ * Bumped development rake version from 0.10 to 0.13 for security fixes
16
+ * Fixed warning about string defaulting to string (#2)
17
+
18
+ ## 0.3.0 / 2019-07-02
19
+
20
+ * Added enumerator-based result access methods: `#rows` and `#records`
21
+ * Fixed bug dropping headers from memoized rows across `#to_h` and `#to_a(header_row: true)`
22
+
1
23
  ## 0.2.0 / 2019-03-20
2
24
 
3
25
  * Added support for NULL values. Columns with a nullable status of "NULLABLE" or "UNKNOWN" will return nil for NULL values
data/Gemfile.lock CHANGED
@@ -1,33 +1,36 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- athens (0.2.0)
4
+ athens (0.3.4)
5
5
  aws-sdk-athena (~> 1)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- aws-eventstream (1.0.1)
11
- aws-partitions (1.136.0)
12
- aws-sdk-athena (1.7.0)
13
- aws-sdk-core (~> 3, >= 3.39.0)
14
- aws-sigv4 (~> 1.0)
15
- aws-sdk-core (3.46.0)
16
- aws-eventstream (~> 1.0)
17
- aws-partitions (~> 1.0)
18
- aws-sigv4 (~> 1.0)
10
+ aws-eventstream (1.1.0)
11
+ aws-partitions (1.430.0)
12
+ aws-sdk-athena (1.35.0)
13
+ aws-sdk-core (~> 3, >= 3.112.0)
14
+ aws-sigv4 (~> 1.1)
15
+ aws-sdk-core (3.112.0)
16
+ aws-eventstream (~> 1, >= 1.0.2)
17
+ aws-partitions (~> 1, >= 1.239.0)
18
+ aws-sigv4 (~> 1.1)
19
19
  jmespath (~> 1.0)
20
- aws-sigv4 (1.0.3)
20
+ aws-sigv4 (1.2.2)
21
+ aws-eventstream (~> 1, >= 1.0.2)
21
22
  jmespath (1.4.0)
22
- rake (10.5.0)
23
+ rake (13.0.1)
24
+ rexml (3.2.4)
23
25
 
24
26
  PLATFORMS
25
27
  ruby
26
28
 
27
29
  DEPENDENCIES
28
30
  athens!
29
- bundler (~> 1.17)
30
- rake (~> 10.0)
31
+ bundler (>= 1.17)
32
+ rake (~> 13.0)
33
+ rexml (~> 3.2)
31
34
 
32
35
  BUNDLED WITH
33
- 1.17.2
36
+ 2.2.5
data/README.md CHANGED
@@ -44,8 +44,8 @@ When your query is done, grab the results as an array:
44
44
  ```ruby
45
45
  results = query.to_a
46
46
  # [
47
- # ['column_1', 'column_2', 'column_3'],
48
- # [15, 'data', true],
47
+ # ['column_1', 'column_2', 'column_3'],
48
+ # [15, 'data', true],
49
49
  # [20, 'foo', false],
50
50
  # ...
51
51
  # ]
@@ -55,12 +55,29 @@ Or as a hash (which is really an array where each row is a hash):
55
55
  ```ruby
56
56
  results = query.to_h
57
57
  # [
58
- # {'column_1': 15, 'column_2': 'data', 'column_3': true},
58
+ # {'column_1': 15, 'column_2': 'data', 'column_3': true},
59
59
  # {'column_1': 20, 'column_2': 'foo', 'column_3': false},
60
60
  # ...
61
61
  # ]
62
62
  ```
63
63
 
64
+ Results are also available as unbuffered enumerators of row arrays:
65
+ ```ruby
66
+ query.rows.each {|row| ...}
67
+ # ['column_1', 'column_2', 'column_3']
68
+ # [15, 'data', true]
69
+ # [20, 'foo', false],
70
+ # ...
71
+ ```
72
+
73
+ Or hashes:
74
+ ```ruby
75
+ query.records.each {|record| ...}
76
+ # {'column_1': 15, 'column_2': 'data', 'column_3': true}
77
+ # {'column_1': 20, 'column_2': 'foo', 'column_3': false}
78
+ # ...
79
+ ```
80
+
64
81
  Athens attempts to parse the sql data types into their ruby equivalents, although there's currently no support for the more complex Array/Map types.
65
82
 
66
83
  ### Configuration
@@ -70,9 +87,10 @@ Configure your AWS settings in an `Athens.configure` block (in rails put this in
70
87
  ```ruby
71
88
  Athens.configure do |config|
72
89
  config.output_location = "s3://my-bucket/my-folder/athena/results/" # Required
73
- config.aws_access_key = 'access' # Optional
74
- config.aws_secret_key = 'secret' # Optional
75
- config.aws_region = 'us-east-1' # Optional
90
+ config.aws_access_key = 'access' # Optional
91
+ config.aws_secret_key = 'secret' # Optional
92
+ config.aws_region = 'us-east-1' # Optional
93
+ config.wait_polling_period = 0.25 # Optional - What period should we poll for the complete query?
76
94
  end
77
95
  ```
78
96
 
@@ -129,6 +147,13 @@ query.cancel # Attempts to cancel an in-progress query, returns true or false
129
147
  query.to_a(header_row: false) # If you want your query results returned without a header row of column names
130
148
  ```
131
149
 
150
+ The execute method also optionally supports the `request_token` and `work_group` [parameters](https://docs.aws.amazon.com/athena/latest/APIReference/API_StartQueryExecution.html#API_StartQueryExecution_RequestSyntax):
151
+
152
+ ```ruby
153
+ conn = Athens::Connection.new(database: 'sample')
154
+ query = conn.execute("SELECT * FROM mytable", request_token: single_use_token, work_group: my_work_group)
155
+ ```
156
+
132
157
  ## Development
133
158
 
134
159
  After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -148,3 +173,4 @@ The gem is available as open source under the terms of the [WTFPL License](http:
148
173
  ## Code of Conduct
149
174
 
150
175
  Everyone interacting in the Athens project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/getletterpress/athens/blob/master/CODE_OF_CONDUCT.md).
176
+
data/Rakefile CHANGED
@@ -1,2 +1 @@
1
1
  require "bundler/gem_tasks"
2
- task :default => :spec
data/athens.gemspec CHANGED
@@ -32,10 +32,11 @@ Gem::Specification.new do |spec|
32
32
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
33
33
  spec.require_paths = ["lib"]
34
34
 
35
- spec.required_ruby_version = '~> 2.4'
35
+ spec.required_ruby_version = '>= 2.4'
36
36
 
37
37
  spec.add_dependency "aws-sdk-athena", "~> 1"
38
38
 
39
- spec.add_development_dependency "bundler", "~> 1.17"
40
- spec.add_development_dependency "rake", "~> 10.0"
39
+ spec.add_development_dependency "bundler", ">= 1.17"
40
+ spec.add_development_dependency "rake", "~> 13.0"
41
+ spec.add_development_dependency "rexml", "~> 3.2"
41
42
  end
@@ -1,15 +1,17 @@
1
1
  module Athens
2
2
  class Configuration
3
- attr_accessor :aws_access_key,
3
+ attr_accessor :aws_access_key,
4
4
  :aws_secret_key,
5
5
  :aws_region,
6
- :output_location
6
+ :output_location,
7
+ :wait_polling_period
7
8
 
8
9
  def initialize
9
10
  @aws_access_key = nil
10
11
  @aws_secret_key = nil
11
12
  @aws_region = nil
12
13
  @output_location = nil
14
+ @wait_polling_period = 0.25
13
15
  end
14
16
  end
15
- end
17
+ end
@@ -8,7 +8,7 @@ module Athens
8
8
  def initialize(database: nil, aws_client_override: {})
9
9
  @database_name = database
10
10
 
11
- client_config = {
11
+ client_config = {
12
12
  access_key_id: Athens.configuration.aws_access_key,
13
13
  secret_access_key: Athens.configuration.aws_secret_key,
14
14
  region: Athens.configuration.aws_region
@@ -19,26 +19,28 @@ module Athens
19
19
 
20
20
  # Runs a query against Athena, returning an Athens::Query object
21
21
  # that you can use to wait for it to finish or get the results
22
- def execute(query)
22
+ def execute(query, request_token: nil, work_group: nil)
23
23
  if @database_name
24
24
  resp = @client.start_query_execution(
25
25
  query_string: query,
26
26
  query_execution_context: context,
27
- result_configuration: result_config
27
+ result_configuration: result_config,
28
+ client_request_token: request_token,
29
+ work_group: work_group
28
30
  )
29
31
  else
30
32
  resp = @client.start_query_execution(
31
33
  query_string: query,
32
34
  result_configuration: result_config
33
35
  )
34
- end
36
+ end
35
37
 
36
38
  return Athens::Query.new(self, resp.query_execution_id)
37
39
  end
38
40
 
39
41
  private
40
42
 
41
- def context
43
+ def context
42
44
  Aws::Athena::Types::QueryExecutionContext.new(database: @database_name)
43
45
  end
44
46
 
data/lib/athens/query.rb CHANGED
@@ -49,7 +49,7 @@ module Athens
49
49
  end
50
50
 
51
51
  # Wait a bit and check again
52
- sleep(0.25)
52
+ sleep(Athens.configuration.wait_polling_period.to_f)
53
53
  end
54
54
  end
55
55
 
@@ -69,12 +69,10 @@ module Athens
69
69
  end
70
70
  end
71
71
 
72
- def to_a(header_row: true)
72
+ def rows
73
73
  raise InvalidRequestError.new("Query must be in SUCCEEDED state to return results") unless @state == 'SUCCEEDED'
74
74
 
75
- if @results.nil?
76
- # Need to load and map all of the rows from the original result
77
- @results = []
75
+ Enumerator.new do |y|
78
76
  result = @connection.client.get_query_results({query_execution_id: @query_execution_id})
79
77
 
80
78
  metadata = result.result_set.result_set_metadata
@@ -85,53 +83,43 @@ module Athens
85
83
  break if rows.empty?
86
84
 
87
85
  if first
88
- @results << rows.shift.data.map {|col| col.var_char_value}
86
+ y << rows.shift.data.map {|col| col.var_char_value}
89
87
  first = false
90
88
  end
91
89
 
92
- rows.each do |row|
93
- @results << map_types(metadata, row)
94
- end
90
+ rows.each {|row| y << map_types(metadata, row)}
95
91
 
96
- if result.next_token
97
- result = @connection.client.get_query_results({
98
- query_execution_id: @query_execution_id,
99
- next_token: result.next_token
100
- })
101
- else
102
- # No more rows, break out and return our mapped data
103
- break
104
- end
105
- end
106
- end
92
+ break unless result.next_token
107
93
 
108
- if header_row
109
- return @results
110
- else
111
- return @results[1, @results.size]
94
+ result = @connection.client.get_query_results({
95
+ query_execution_id: @query_execution_id,
96
+ next_token: result.next_token
97
+ })
98
+ end
112
99
  end
113
100
  end
114
101
 
115
- def to_h
116
- if @hash_results.nil?
117
- all_rows = self.to_a(header_row: true)
118
-
119
- headers = all_rows.shift
102
+ def records
103
+ Enumerator.new do |y|
104
+ headers = nil
120
105
 
121
- @hash_results = []
122
-
123
- unless headers.nil?
124
- all_rows.each do |row|
125
- map = {}
126
- headers.each_with_index do |header, index|
127
- map[header] = row[index]
128
- end
129
- @hash_results << map
106
+ rows.each_with_index do |row|
107
+ if headers.nil?
108
+ headers = row
109
+ next
130
110
  end
111
+
112
+ y << Hash[headers.zip(row)]
131
113
  end
132
114
  end
115
+ end
116
+
117
+ def to_a(header_row: true)
118
+ (@results ||= rows.to_a).drop(header_row ? 0 : 1)
119
+ end
133
120
 
134
- return @hash_results
121
+ def to_h
122
+ @hash_results ||= records.to_a
135
123
  end
136
124
 
137
125
  private
@@ -163,7 +151,7 @@ module Athens
163
151
  mapped << data.to_i
164
152
  when 'timestamp'
165
153
  mapped << Time.parse(data)
166
- when 'varchar'
154
+ when 'varchar', 'string'
167
155
  mapped << data
168
156
  when 'float', 'double'
169
157
  mapped << data.to_f
@@ -185,9 +173,8 @@ module Athens
185
173
  end
186
174
 
187
175
  return mapped
188
- end
176
+ end
189
177
 
190
178
 
191
179
  end
192
180
  end
193
-
@@ -1,3 +1,3 @@
1
1
  module Athens
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.4"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: athens
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Schulte
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-03-20 00:00:00.000000000 Z
11
+ date: 2021-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-athena
@@ -28,14 +28,14 @@ dependencies:
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.17'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.17'
41
41
  - !ruby/object:Gem::Dependency
@@ -44,14 +44,28 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '10.0'
47
+ version: '13.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '13.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rexml
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.2'
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - "~>"
53
67
  - !ruby/object:Gem::Version
54
- version: '10.0'
68
+ version: '3.2'
55
69
  description: Allows you to easily access AWS Athena databases and run queries
56
70
  email:
57
71
  - chris@oceanbreezesoftware.com
@@ -84,13 +98,13 @@ metadata:
84
98
  homepage_uri: https://github.com/getletterpress/athens
85
99
  source_code_uri: https://github.com/getletterpress/athens
86
100
  changelog_uri: https://github.com/getletterpress/athens/CHANGELOG.md
87
- post_install_message:
101
+ post_install_message:
88
102
  rdoc_options: []
89
103
  require_paths:
90
104
  - lib
91
105
  required_ruby_version: !ruby/object:Gem::Requirement
92
106
  requirements:
93
- - - "~>"
107
+ - - ">="
94
108
  - !ruby/object:Gem::Version
95
109
  version: '2.4'
96
110
  required_rubygems_version: !ruby/object:Gem::Requirement
@@ -99,9 +113,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
113
  - !ruby/object:Gem::Version
100
114
  version: '0'
101
115
  requirements: []
102
- rubyforge_project:
103
- rubygems_version: 2.7.8
104
- signing_key:
116
+ rubygems_version: 3.1.4
117
+ signing_key:
105
118
  specification_version: 4
106
119
  summary: Run simple SQL queries in AWS Athena
107
120
  test_files: []