athens 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: '02197372c02d45a05efd88997b4cd8c01d66c869eafd6ca867f86da791ffe7b4'
4
+ data.tar.gz: 1753f4f6986c4fedf82f09d9a6d9ebe0b9fb630d59261011fc3c0667108e4ed0
5
+ SHA512:
6
+ metadata.gz: facc871951901270b2b61410ae471cd6d62fcb33d2a914da76855e41fbccfb5039ee4e0d086deced77bcf39bf8c07fe865c635d6659093a2acac181291c78c2a
7
+ data.tar.gz: feca9c73d6145784b74dc4ce5442c2b764efda51719ff58e5fa6896d8dfd89186224d7aaa4f9ae282d58043bf5aa4f0e3576998d40ec0d9983c51d917d6d8022
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ /.vagrant/
11
+ /ubuntu-xenial-16.04-cloudimg-console.log
@@ -0,0 +1,3 @@
1
+ ## 0.1.0 / 2019-03-01
2
+
3
+ * Initial release!
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at TODO: Write your email address. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in athens.gemspec
6
+ gemspec
@@ -0,0 +1,33 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ athens (0.1.0)
5
+ aws-sdk-athena (~> 1)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
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)
19
+ jmespath (~> 1.0)
20
+ aws-sigv4 (1.0.3)
21
+ jmespath (1.4.0)
22
+ rake (10.5.0)
23
+
24
+ PLATFORMS
25
+ ruby
26
+
27
+ DEPENDENCIES
28
+ athens!
29
+ bundler (~> 1.17)
30
+ rake (~> 10.0)
31
+
32
+ BUNDLED WITH
33
+ 1.17.2
@@ -0,0 +1,14 @@
1
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2
+ Version 2, December 2004
3
+
4
+ Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
5
+
6
+ Everyone is permitted to copy and distribute verbatim or modified
7
+ copies of this license document, and changing it is allowed as long
8
+ as the name is changed.
9
+
10
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12
+
13
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
14
+
@@ -0,0 +1,150 @@
1
+ # Athens
2
+
3
+ Athens is a wrapper around the standard AWS athena sdk, with a much simpler interface for executing queries and processing results.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'athens'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install athens
20
+
21
+ ## Usage
22
+
23
+ ### Quickstart
24
+
25
+ There are two main classes for Athens, the `Connection` and the `Query`. First "open" a connection to the database:
26
+
27
+ ```ruby
28
+ conn = Athens::Connection.new(database: 'sample')
29
+ ```
30
+
31
+ Then start a query:
32
+ ```ruby
33
+ query = conn.execute("SELECT * FROM mytable")
34
+ ```
35
+
36
+ That kicks off an Athena query in the background. If you want you can just wait for it to finish:
37
+ ```ruby
38
+ query.wait
39
+ # or
40
+ query.wait(5) # Wait 5 seconds at most
41
+ ```
42
+
43
+ When your query is done, grab the results as an array:
44
+ ```ruby
45
+ results = query.to_a
46
+ # [
47
+ # ['column_1', 'column_2', 'column_3'],
48
+ # [15, 'data', true],
49
+ # [20, 'foo', false],
50
+ # ...
51
+ # ]
52
+ ```
53
+
54
+ Or as a hash (which is really an array where each row is a hash):
55
+ ```ruby
56
+ results = query.to_h
57
+ # [
58
+ # {'column_1': 15, 'column_2': 'data', 'column_3': true},
59
+ # {'column_1': 20, 'column_2': 'foo', 'column_3': false},
60
+ # ...
61
+ # ]
62
+ ```
63
+
64
+ 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
+
66
+ ### Configuration
67
+
68
+ Configure your AWS settings in an `Athens.configure` block (in rails put this in `config/initializers/athens.rb`):
69
+
70
+ ```ruby
71
+ Athens.configure do |config|
72
+ 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
76
+ end
77
+ ```
78
+
79
+ The aws parameters are all "optional", in that you can omit those in favor of any of the standard AWS configuration options (i.e. IAM Roles, environment variables, .aws/credentials files).
80
+
81
+ You can also override the AWS client configuration on a per-connection basis:
82
+
83
+ ```ruby
84
+ conn = Athens::Connection.new(aws_client_override: {})
85
+ ```
86
+
87
+ Take a look at the [AWS Athena SDK](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/Athena/Client.html#initialize-instance_method) for a list of all the available options.
88
+
89
+ ### Advanced Usage
90
+
91
+ Providing a database name to the connection is optional, if you omit the name you'll have to specify it in your query:
92
+
93
+ ```ruby
94
+ conn = Athens::Connection.new(database 'sample')
95
+ query = conn.execute("SELECT * FROM mytable")
96
+
97
+ # or
98
+
99
+ conn = Athens::Connection.new
100
+ query = conn.execute("SELECT * FROM sample.mytable")
101
+ ```
102
+
103
+ While waiting for a query to finish, you could get one of two exceptions:
104
+
105
+ ```ruby
106
+ conn = Athens::Connection.new(database 'sample')
107
+ query = conn.execute("SELECT * FROM mytable")
108
+
109
+ begin
110
+ query.wait()
111
+ rescue Athens::QueryFailedError => qfe
112
+ # Query returned a failure message, qfe.message has details
113
+ rescue Athens::QueryCancelledError => qce
114
+ # Query was canceled (usually by the user), qce.message has details
115
+ end
116
+ ```
117
+
118
+ When a query is running you can do a few things:
119
+
120
+ ```ruby
121
+ conn = Athens::Connection.new(database: 'sample')
122
+ query = conn.execute("SELECT * FROM mytable")
123
+
124
+ query.state # Returns one of QUEUED, RUNNING, SUCCEEDED, FAILED, or CANCELLED (https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/Athena/Types/QueryExecutionStatus.html#state-instance_method)
125
+ query.state_reason # Further details from AWS about the state
126
+ query.query_execution_id # The id of the query returned from AWS
127
+ query.cancel # Attempts to cancel an in-progress query, returns true or false (if the query has already finished this will return false)
128
+
129
+ query.to_a(header_row: false) # If you want your query results returned without a header row of column names
130
+ ```
131
+
132
+ ## Development
133
+
134
+ 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.
135
+
136
+ If you want you can use Vagrant instead, there's already a `Vagrantfile` so a simple `vagrant up` should get you setup.
137
+
138
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
139
+
140
+ ## Contributing
141
+
142
+ Bug reports and pull requests are welcome on GitHub at https://github.com/getletterpress/athens. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
143
+
144
+ ## License
145
+
146
+ The gem is available as open source under the terms of the [WTFPL License](http://www.wtfpl.net/).
147
+
148
+ ## Code of Conduct
149
+
150
+ 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).
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -0,0 +1,38 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ # Provisioning script
5
+ $script = <<SCRIPT
6
+ echo "*** Updating packages"
7
+
8
+ sudo DEBIAN_FRONTEND=noninteractive apt-get install -y aptitude
9
+ sudo DEBIAN_FRONTEND=noninteractive aptitude update
10
+ sudo DEBIAN_FRONTEND=noninteractive aptitude -y safe-upgrade
11
+
12
+ echo "*** Installing new packages"
13
+ sudo DEBIAN_FRONTEND=noninteractive aptitude install -y curl git-core vim
14
+
15
+ if rvm -v 2>/dev/null; then
16
+ echo "*** rvm already installed, skipping"
17
+ else
18
+ echo "*** Installing rvm"
19
+ gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
20
+ curl -sSL https://get.rvm.io | bash -s stable --ruby
21
+ echo "gem: --no-document" > ~/.gemrc
22
+
23
+ echo "*** Finished installing rvm"
24
+ fi
25
+
26
+ echo "*********************"
27
+ echo "PROVISIONING FINISHED"
28
+ echo "*********************"
29
+ SCRIPT
30
+
31
+
32
+ Vagrant.configure('2') do |config|
33
+ config.vm.box = "ubuntu/xenial64"
34
+ config.vm.hostname = 'athens-dev'
35
+
36
+ # Provision the machine with the shell script above
37
+ config.vm.provision "shell", inline: $script, privileged: false
38
+ end
@@ -0,0 +1,41 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "athens/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "athens"
8
+ spec.version = Athens::VERSION
9
+ spec.authors = ["Chris Schulte"]
10
+ spec.email = ["chris@oceanbreezesoftware.com"]
11
+
12
+ spec.summary = %q{Run simple SQL queries in AWS Athena}
13
+ spec.description = %q{Allows you to easily access AWS Athena databases and run queries}
14
+ spec.homepage = "https://github.com/getletterpress/athens"
15
+ spec.license = "WTFPL"
16
+
17
+ if spec.respond_to?(:metadata)
18
+ spec.metadata["homepage_uri"] = spec.homepage
19
+ spec.metadata["source_code_uri"] = "https://github.com/getletterpress/athens"
20
+ spec.metadata["changelog_uri"] = "https://github.com/getletterpress/athens/CHANGELOG.md"
21
+ else
22
+ raise "RubyGems 2.0 or newer is required to protect against " \
23
+ "public gem pushes."
24
+ end
25
+
26
+ # Specify which files should be added to the gem when it is released.
27
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
28
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
29
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
30
+ end
31
+ spec.bindir = "exe"
32
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
33
+ spec.require_paths = ["lib"]
34
+
35
+ spec.required_ruby_version = '~> 2.4'
36
+
37
+ spec.add_dependency "aws-sdk-athena", "~> 1"
38
+
39
+ spec.add_development_dependency "bundler", "~> 1.17"
40
+ spec.add_development_dependency "rake", "~> 10.0"
41
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "athens"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,25 @@
1
+ require "athens/error"
2
+ require "athens/version"
3
+ require "athens/configuration"
4
+ require "athens/connection"
5
+ require "athens/query"
6
+
7
+ require 'aws-sdk-athena'
8
+
9
+ module Athens
10
+ class << self
11
+ attr_accessor :configuration
12
+ end
13
+
14
+ def self.configuration
15
+ @configuration ||= Configuration.new
16
+ end
17
+
18
+ def self.reset
19
+ @configuration = Configuration.new
20
+ end
21
+
22
+ def self.configure
23
+ yield(configuration)
24
+ end
25
+ end
@@ -0,0 +1,15 @@
1
+ module Athens
2
+ class Configuration
3
+ attr_accessor :aws_access_key,
4
+ :aws_secret_key,
5
+ :aws_region,
6
+ :output_location
7
+
8
+ def initialize
9
+ @aws_access_key = nil
10
+ @aws_secret_key = nil
11
+ @aws_region = nil
12
+ @output_location = nil
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,55 @@
1
+ require 'bigdecimal'
2
+
3
+ module Athens
4
+ class Connection
5
+ attr_reader :database_name
6
+ attr_reader :client
7
+
8
+ def initialize(database: nil, aws_client_override: {})
9
+ @database_name = database
10
+
11
+ client_config = {
12
+ access_key_id: Athens.configuration.aws_access_key,
13
+ secret_access_key: Athens.configuration.aws_secret_key,
14
+ region: Athens.configuration.aws_region
15
+ }.merge(aws_client_override).compact
16
+
17
+ @client = Aws::Athena::Client.new(client_config)
18
+ end
19
+
20
+ # Runs a query against Athena, returning an Athens::Query object
21
+ # that you can use to wait for it to finish or get the results
22
+ def execute(query)
23
+ if @database_name
24
+ resp = @client.start_query_execution(
25
+ query_string: query,
26
+ query_execution_context: context,
27
+ result_configuration: result_config
28
+ )
29
+ else
30
+ resp = @client.start_query_execution(
31
+ query_string: query,
32
+ result_configuration: result_config
33
+ )
34
+ end
35
+
36
+ return Athens::Query.new(self, resp.query_execution_id)
37
+ end
38
+
39
+ private
40
+
41
+ def context
42
+ Aws::Athena::Types::QueryExecutionContext.new(database: @database_name)
43
+ end
44
+
45
+ def result_config
46
+ Aws::Athena::Types::ResultConfiguration.new(
47
+ output_location: Athens.configuration.output_location,
48
+ encryption_configuration: {
49
+ encryption_option: "SSE_S3"
50
+ }
51
+ )
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,8 @@
1
+ module Athens
2
+ class Error < StandardError; end
3
+
4
+ class QueryFailedError < Error; end
5
+ class QueryCancelledError < Error; end
6
+ class InvalidRequestError < Error; end
7
+
8
+ end
@@ -0,0 +1,186 @@
1
+ module Athens
2
+ class Query
3
+ attr_reader :query_execution_id
4
+
5
+ def initialize(connection, query_execution_id)
6
+ @connection = connection
7
+ @query_execution_id = query_execution_id
8
+ @state = nil
9
+ @state_reason = nil
10
+ @cancelled = false
11
+
12
+ @results = nil
13
+ @hash_results = nil
14
+
15
+ version = RUBY_VERSION.split('.').map {|v| v.to_i}
16
+ @decimal_without_new = (version[0] >= 2 && version[1] >= 5)
17
+ end
18
+
19
+ def state
20
+ refresh_state if state_needs_refresh?
21
+ @state
22
+ end
23
+
24
+ def state_reason
25
+ refresh_state if state_needs_refresh?
26
+ @state_reason
27
+ end
28
+
29
+ def wait(max_seconds = nil)
30
+ if max_seconds.nil?
31
+ stop_at = nil
32
+ else
33
+ stop_at = Time.now + max_seconds
34
+ end
35
+
36
+ while true
37
+ if stop_at != nil && Time.now > stop_at
38
+ return false
39
+ end
40
+
41
+ refresh_state
42
+
43
+ if @state == 'SUCCEEDED'
44
+ return true
45
+ elsif @state == 'FAILED'
46
+ raise QueryFailedError.new(@state_reason)
47
+ elsif state == 'CANCELLED'
48
+ raise QueryCancelledError.new(@state_reason)
49
+ end
50
+
51
+ # Wait a bit and check again
52
+ sleep(0.25)
53
+ end
54
+ end
55
+
56
+ def cancel
57
+ unless @cancelled
58
+ resp = @connection.client.stop_query_execution({
59
+ query_execution_id: @query_execution_id
60
+ })
61
+ @cancelled = true
62
+ refresh_state
63
+ end
64
+
65
+ if @state == 'CANCELLED'
66
+ return true
67
+ else
68
+ return false
69
+ end
70
+ end
71
+
72
+ def to_a(header_row: true)
73
+ raise InvalidRequestError.new("Query must be in SUCCEEDED state to return results") unless @state == 'SUCCEEDED'
74
+
75
+ if @results.nil?
76
+ # Need to load and map all of the rows from the original result
77
+ @results = []
78
+ result = @connection.client.get_query_results({query_execution_id: @query_execution_id})
79
+
80
+ metadata = result.result_set.result_set_metadata
81
+ first = true
82
+
83
+ while true
84
+ rows = result.result_set.rows
85
+ break if rows.empty?
86
+
87
+ if first
88
+ @results << rows.shift.data.map {|col| col.var_char_value}
89
+ first = false
90
+ end
91
+
92
+ rows.each do |row|
93
+ @results << map_types(metadata, row)
94
+ end
95
+
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
107
+
108
+ if header_row
109
+ return @results
110
+ else
111
+ return @results[1, @results.size]
112
+ end
113
+ end
114
+
115
+ def to_h
116
+ if @hash_results.nil?
117
+ all_rows = self.to_a(header_row: true)
118
+
119
+ headers = all_rows.shift
120
+
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
130
+ end
131
+ end
132
+ end
133
+
134
+ return @hash_results
135
+ end
136
+
137
+ private
138
+ def state_needs_refresh?
139
+ @state.nil? || (['QUEUED', 'RUNNING'].include?(@state))
140
+ end
141
+
142
+ def refresh_state
143
+ resp = @connection.client.get_query_execution({query_execution_id: @query_execution_id})
144
+
145
+ @state = resp.query_execution.status.state
146
+ @state_reason = resp.query_execution.status.state_change_reason
147
+ end
148
+
149
+ def map_types(metadata, row)
150
+ mapped = []
151
+
152
+ metadata.column_info.each_with_index do |col, index|
153
+ data = row.data[index].var_char_value
154
+
155
+ case col.type
156
+ when 'tinyint', 'smallint', 'int', 'integer', 'bigint'
157
+ mapped << data.to_i
158
+ when 'timestamp'
159
+ mapped << Time.parse(data)
160
+ when 'varchar'
161
+ mapped << data
162
+ when 'float', 'double'
163
+ mapped << data.to_f
164
+ when 'decimal'
165
+ if @decimal_without_new
166
+ mapped << BigDecimal(data)
167
+ else
168
+ mapped << BigDecimal.new(data)
169
+ end
170
+ when 'date'
171
+ mapped << Date.parse(data)
172
+ when 'boolean'
173
+ mapped << (data == "true")
174
+ else
175
+ puts "WARNING: Unsupported type: #{col.type}, defaulting to string"
176
+ mapped << data
177
+ end
178
+ end
179
+
180
+ return mapped
181
+ end
182
+
183
+
184
+ end
185
+ end
186
+
@@ -0,0 +1,3 @@
1
+ module Athens
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: athens
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Chris Schulte
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-03-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk-athena
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.17'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.17'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ description: Allows you to easily access AWS Athena databases and run queries
56
+ email:
57
+ - chris@oceanbreezesoftware.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - CHANGELOG.md
64
+ - CODE_OF_CONDUCT.md
65
+ - Gemfile
66
+ - Gemfile.lock
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - Vagrantfile
71
+ - athens.gemspec
72
+ - bin/console
73
+ - bin/setup
74
+ - lib/athens.rb
75
+ - lib/athens/configuration.rb
76
+ - lib/athens/connection.rb
77
+ - lib/athens/error.rb
78
+ - lib/athens/query.rb
79
+ - lib/athens/version.rb
80
+ homepage: https://github.com/getletterpress/athens
81
+ licenses:
82
+ - WTFPL
83
+ metadata:
84
+ homepage_uri: https://github.com/getletterpress/athens
85
+ source_code_uri: https://github.com/getletterpress/athens
86
+ changelog_uri: https://github.com/getletterpress/athens/CHANGELOG.md
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '2.4'
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubyforge_project:
103
+ rubygems_version: 2.7.8
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: Run simple SQL queries in AWS Athena
107
+ test_files: []