queuery_client 0.9.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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