queuery_client 0.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 312f2cfd1168a1af9b581ca43dcaad9e46ac7377
4
- data.tar.gz: e0e6c8247b14c92f9145a7155f18d619cdb8541d
2
+ SHA256:
3
+ metadata.gz: c873a091add34619c21ef63bd324a41205dfdc4f509a9b4574a2a31c2c121e4b
4
+ data.tar.gz: 5b184dba90213ba0f022302ae2dc99e59ec491189e4c7f65c5c05b24d3497ec3
5
5
  SHA512:
6
- metadata.gz: 5e20bbf161970e050375276242206cc1206d733c83691c8f86a66d45a78a0fd475f351134f9a1f8ddeadcfa88222b67a148e3ebbd6de80daa52eb3209208fdc7
7
- data.tar.gz: 73306d35879474ba8d92ad077f4d6f47279041332979abe4d28302ae2d2e964795b69d22d2f44b9ca005021dce7c1ba53fdd34681dc3ac77024102c686b7dd20
6
+ metadata.gz: 59fb860a84e25e604f160cd8209aecebd742b1a4e36fd84e3591bc4b7a0bc4f6c8ecb3482eb001c22eae379bec109ebf78ebe78a9f435a1c99b05f5e86299a56
7
+ data.tar.gz: a56489e0fa77068fc548f9b4c98fc9215f962c80ec2fe197f1958e05538992884ddc7aaa76bd2f86c43980db9c31437f24485f8371ea4739c867ce7837bd7c45
@@ -3,7 +3,8 @@ require "queuery_client/configuration"
3
3
  require "queuery_client/basic_auth_garage_client"
4
4
  require "queuery_client/query_error"
5
5
  require "queuery_client/client"
6
- require "queuery_client/queuery_data_file_bundle"
6
+ require "queuery_client/url_data_file_bundle"
7
+ require "queuery_client/s3_data_file_bundle"
7
8
 
8
9
  module QueueryClient
9
10
  class << self
@@ -32,7 +32,7 @@ module QueueryClient
32
32
  query = query_and_wait(select_stmt, values)
33
33
  case query.status
34
34
  when 'success'
35
- QueueryDataFileBundle.new(
35
+ UrlDataFileBundle.new(
36
36
  query.data_file_urls,
37
37
  s3_prefix: query.s3_prefix,
38
38
  )
@@ -0,0 +1,26 @@
1
+ require 'redshift_csv_file'
2
+ require 'zlib'
3
+
4
+ module QueueryClient
5
+ class DataFile
6
+ def data_object?
7
+ /\.csv(?:\.|\z)/ =~ File.basename(key)
8
+ end
9
+
10
+ def gzipped_object?
11
+ File.extname(key) == '.gz'
12
+ end
13
+
14
+ def each_row(&block)
15
+ f = open
16
+ begin
17
+ if gzipped_object?
18
+ f = Zlib::GzipReader.new(f)
19
+ end
20
+ RedshiftCsvFile.new(f).each(&block)
21
+ ensure
22
+ f.close
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,15 @@
1
+ module QueueryClient
2
+ class DataFileBundle
3
+ # abstract data_files :: [DataFile]
4
+
5
+ def each_row(&block)
6
+ data_files.each do |file|
7
+ if file.data_object?
8
+ file.each_row(&block)
9
+ end
10
+ end
11
+ end
12
+
13
+ alias each each_row
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ require 'queuery_client/data_file'
2
+ require 'forwardable'
3
+
4
+ module QueueryClient
5
+ class S3DataFile < DataFile
6
+ extend Forwardable
7
+
8
+ def initialize(object)
9
+ @object = object
10
+ end
11
+
12
+ def_delegators '@object', :url, :key, :presigned_url
13
+
14
+ def open
15
+ @object.get.body
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,28 @@
1
+ require 'queuery_client/data_file_bundle'
2
+ require 'queuery_client/s3_data_file'
3
+ require 'aws-sdk-s3'
4
+ require 'logger'
5
+
6
+ module QueueryClient
7
+ class S3DataFileBundle < DataFileBundle
8
+ def initialize(bucket, prefix, s3_client: nil, logger: Logger.new($stderr))
9
+ @s3_client = s3_client || Aws::S3::Client.new # Use env to inject credentials
10
+ @bucket = bucket
11
+ @prefix = prefix
12
+ @logger = logger
13
+ end
14
+
15
+ attr_reader :bucket
16
+ attr_reader :prefix
17
+ attr_reader :logger
18
+
19
+ def url
20
+ "s3://#{@bucket}/#{@prefix}"
21
+ end
22
+
23
+ def data_files
24
+ b = Aws::S3::Resource.new(client: @s3_client).bucket(@bucket)
25
+ b.objects(prefix: @prefix).map {|obj| S3DataFile.new(obj) }
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,27 @@
1
+ require 'queuery_client/data_file'
2
+ require 'net/http'
3
+ require 'stringio'
4
+
5
+ module QueueryClient
6
+ class UrlDataFile < DataFile
7
+ def initialize(url)
8
+ @url = url
9
+ end
10
+
11
+ attr_reader :url
12
+
13
+ def key
14
+ @url.path
15
+ end
16
+
17
+ def open
18
+ http = Net::HTTP.new(@url.host, @url.port)
19
+ http.use_ssl = (@url.scheme.downcase == 'https')
20
+ content = http.start {
21
+ res = http.get(@url.request_uri)
22
+ res.body
23
+ }
24
+ StringIO.new(content)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,32 @@
1
+ require 'queuery_client/data_file_bundle'
2
+ require 'queuery_client/url_data_file'
3
+ require 'uri'
4
+ require 'logger'
5
+
6
+ module QueueryClient
7
+ class UrlDataFileBundle < DataFileBundle
8
+ def initialize(urls, s3_prefix:, logger: Logger.new($stderr))
9
+ raise ArgumentError, 'no URL given' if urls.empty?
10
+ @data_files = urls.map {|url| UrlDataFile.new(URI.parse(url)) }
11
+ @s3_prefix = s3_prefix
12
+ @logger = logger
13
+ end
14
+
15
+ attr_reader :data_files
16
+ attr_reader :s3_prefix
17
+
18
+ def url
19
+ uri = data_files.first.url.dup
20
+ uri.query = nil
21
+ uri.path = File.dirname(uri.path)
22
+ uri.to_s
23
+ end
24
+
25
+ def direct(bucket_opts = {}, bundle_opts = {})
26
+ s3_uri = URI.parse(s3_prefix)
27
+ bucket = s3_uri.host
28
+ prefix = s3_uri.path[1..-1] # trim heading slash
29
+ S3DataFileBundle.new(bucket, prefix)
30
+ end
31
+ end
32
+ end
@@ -1,3 +1,3 @@
1
1
  module QueueryClient
2
- VERSION = "0.9.0"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -29,7 +29,8 @@ Gem::Specification.new do |spec|
29
29
  spec.require_paths = ["lib"]
30
30
 
31
31
  spec.add_dependency 'garage_client'
32
- spec.add_dependency "redshift-connector-data_file", ">= 7.1"
32
+ spec.add_dependency 'redshift_csv_file'
33
+ spec.add_dependency 'aws-sdk-s3'
33
34
  spec.add_development_dependency "bundler", "~> 1.13"
34
35
  spec.add_development_dependency "rake", "~> 10.0"
35
36
  spec.add_development_dependency "pry"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: queuery_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hidekazu Kobayashi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-04-04 00:00:00.000000000 Z
11
+ date: 2019-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: garage_client
@@ -25,19 +25,33 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: redshift-connector-data_file
28
+ name: redshift_csv_file
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '7.1'
33
+ version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '7.1'
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: aws-sdk-s3
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -97,11 +111,15 @@ files:
97
111
  - lib/queuery_client/basic_auth_garage_client.rb
98
112
  - lib/queuery_client/client.rb
99
113
  - lib/queuery_client/configuration.rb
114
+ - lib/queuery_client/data_file.rb
115
+ - lib/queuery_client/data_file_bundle.rb
100
116
  - lib/queuery_client/query_error.rb
101
- - lib/queuery_client/queuery_data_file_bundle.rb
117
+ - lib/queuery_client/s3_data_file.rb
118
+ - lib/queuery_client/s3_data_file_bundle.rb
119
+ - lib/queuery_client/url_data_file.rb
120
+ - lib/queuery_client/url_data_file_bundle.rb
102
121
  - lib/queuery_client/version.rb
103
122
  - queuery_client.gemspec
104
- - queuery_client.rb
105
123
  homepage: https://github.com/bricolages/queuery_client
106
124
  licenses:
107
125
  - MIT
@@ -122,8 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
140
  - !ruby/object:Gem::Version
123
141
  version: '0'
124
142
  requirements: []
125
- rubyforge_project:
126
- rubygems_version: 2.6.13
143
+ rubygems_version: 3.0.3
127
144
  signing_key:
128
145
  specification_version: 4
129
146
  summary: Client library for Queuery Redshift HTTP API
@@ -1,30 +0,0 @@
1
- require 'redshift_connector/url_data_file_bundle'
2
- require 'redshift_connector/s3_bucket'
3
- require 'redshift_connector/s3_data_file_bundle'
4
- require 'uri'
5
-
6
- module QueueryClient
7
- class QueueryDataFileBundle < RedshiftConnector::UrlDataFileBundle
8
- def initialize(url, s3_prefix:, **args)
9
- super(url, **args)
10
- @s3_prefix = s3_prefix
11
- end
12
-
13
- attr_reader :s3_prefix
14
-
15
- def url
16
- uri = data_files.first.url.dup
17
- uri.query = nil
18
- uri.path = File.dirname(uri.path)
19
- uri.to_s
20
- end
21
-
22
- def direct(bucket_opts = {}, bundle_opts = {})
23
- s3_uri = URI.parse(s3_prefix)
24
- bucket_name = s3_uri.host
25
- prefix = s3_uri.path[1..-1] # trim heading slash
26
- bucket = RedshiftConnector::S3Bucket.new(bucket: bucket_name, prefix: prefix)
27
- RedshiftConnector::S3DataFileBundle.new(bucket, prefix, format: :redshift_csv)
28
- end
29
- end
30
- end
data/queuery_client.rb DELETED
@@ -1,64 +0,0 @@
1
- require 'uri'
2
- require 'net/http'
3
-
4
- class QueueryClient
5
- class << self
6
- attr_accessor :host
7
- attr_accessor :port
8
-
9
- def query(select_stmt)
10
- client = new(
11
- host: host,
12
- port: port,
13
- )
14
-
15
- res = client.query_and_wait(select_stmt)
16
- RedshiftConnector::UrlDataFileBundle.new(res['data_objects'])
17
- end
18
- end
19
-
20
- def initialize(host:, port: 80)
21
- @host = host
22
- @port = port
23
- end
24
-
25
- def request(req)
26
- res = Net::HTTP.new(@host, @port).request(req)
27
- JSON.parse(res.body)
28
- end
29
-
30
- def request_post(path, params = {})
31
- post_req = Net::HTTP::Post.new(path)
32
- post_req.form_data = params
33
- request(post_req)
34
- end
35
-
36
- def request_get(path)
37
- get_req = Net::HTTP::Get.new(path)
38
- request(get_req)
39
- end
40
-
41
- def query(select_stmt)
42
- request_post('/queries', { q: select_stmt })
43
- end
44
-
45
- def status(job_id)
46
- request_get("/queries/#{job_id}")
47
- end
48
-
49
- def wait_for(job_id)
50
- loop do
51
- res = status(job_id)
52
- case res['status']
53
- when 'success', 'failed'
54
- return res
55
- end
56
- sleep 1
57
- end
58
- end
59
-
60
- def query_and_wait(select_stmt)
61
- res = query(select_stmt)
62
- wait_for(res['job_id'])
63
- end
64
- end