presto-client 0.5.7 → 0.5.8
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/ChangeLog +9 -0
- data/README.md +6 -0
- data/lib/presto/client/client.rb +4 -0
- data/lib/presto/client/faraday_client.rb +154 -0
- data/lib/presto/client/query.rb +18 -64
- data/lib/presto/client/statement_client.rb +1 -78
- data/lib/presto/client/version.rb +1 -1
- data/spec/statement_client_spec.rb +55 -6
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4443f4f6a4ddd03831d7882ca9f296e49b1df7b1
|
4
|
+
data.tar.gz: 075f86339df45b84b868e9d5d04e33983c27b8a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7def55d33d949cff35e14419682c792b821eba0550e1ca791cf49cefa58651c8badfb898b193372afa09290487a2c9fee2cfa58cf1b0bb3b0acac764d2e2b5e5
|
7
|
+
data.tar.gz: f0122e8873e0f037e47231774ba03d1dab3f291ed126edce63a1e6b62733e457b29784ea0f252c5dbf778c18e0ea0773a39905a40ac4d97a8759e758ec9c86b8
|
data/ChangeLog
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
2017-11-13 version 0.5.8
|
2
|
+
|
3
|
+
* Added `Client#kill(query_id)` method.
|
4
|
+
* Added additional checking of internal exceptions so that client doesn't
|
5
|
+
silently return in case when Presto query is killed and Presto returns a
|
6
|
+
valid `200 OK` response with `result_uri: null`.
|
7
|
+
* Fixed `undefined local variable 'body'` error that was possibly happening
|
8
|
+
when Presto returned an unexpected data structure.
|
9
|
+
|
1
10
|
2017-08-28 version 0.5.7
|
2
11
|
* Support a password option with HTTP basic auth
|
3
12
|
* Changed retry timeout from hard coded 2h to configurable default 2min
|
data/README.md
CHANGED
@@ -58,6 +58,12 @@ client.query("select * from sys.node") do |q|
|
|
58
58
|
p row # row is an array
|
59
59
|
}
|
60
60
|
end
|
61
|
+
|
62
|
+
# killing a query
|
63
|
+
query = client.query("select * from sys.node")
|
64
|
+
query_id = query.query_info.query_id
|
65
|
+
query.each_row {|row| ... } # when a thread is processing the query,
|
66
|
+
client.kill(query_id) # another thread / process can kill the query.
|
61
67
|
```
|
62
68
|
|
63
69
|
## Build models
|
data/lib/presto/client/client.rb
CHANGED
@@ -0,0 +1,154 @@
|
|
1
|
+
#
|
2
|
+
# Presto client for Ruby
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
module Presto::Client
|
17
|
+
|
18
|
+
module PrestoHeaders
|
19
|
+
PRESTO_USER = "X-Presto-User"
|
20
|
+
PRESTO_SOURCE = "X-Presto-Source"
|
21
|
+
PRESTO_CATALOG = "X-Presto-Catalog"
|
22
|
+
PRESTO_SCHEMA = "X-Presto-Schema"
|
23
|
+
PRESTO_TIME_ZONE = "X-Presto-Time-Zone"
|
24
|
+
PRESTO_LANGUAGE = "X-Presto-Language"
|
25
|
+
PRESTO_SESSION = "X-Presto-Session"
|
26
|
+
|
27
|
+
PRESTO_CURRENT_STATE = "X-Presto-Current-State"
|
28
|
+
PRESTO_MAX_WAIT = "X-Presto-Max-Wait"
|
29
|
+
PRESTO_MAX_SIZE = "X-Presto-Max-Size"
|
30
|
+
PRESTO_PAGE_SEQUENCE_ID = "X-Presto-Page-Sequence-Id"
|
31
|
+
end
|
32
|
+
|
33
|
+
HEADERS = {
|
34
|
+
"User-Agent" => "presto-ruby/#{VERSION}",
|
35
|
+
}
|
36
|
+
|
37
|
+
def self.faraday_client(options)
|
38
|
+
server = options[:server]
|
39
|
+
unless server
|
40
|
+
raise ArgumentError, ":server option is required"
|
41
|
+
end
|
42
|
+
|
43
|
+
ssl = faraday_ssl_options(options)
|
44
|
+
|
45
|
+
if options[:password] && !ssl
|
46
|
+
raise ArgumentError, "Protocol must be https when passing a password"
|
47
|
+
end
|
48
|
+
|
49
|
+
url = "#{ssl ? "https" : "http"}://#{server}"
|
50
|
+
proxy = options[:http_proxy] || options[:proxy] # :proxy is obsoleted
|
51
|
+
|
52
|
+
faraday_options = {url: url, proxy: "#{proxy}"}
|
53
|
+
faraday_options[:ssl] = ssl if ssl
|
54
|
+
|
55
|
+
faraday = Faraday.new(faraday_options) do |faraday|
|
56
|
+
if options[:user] && options[:password]
|
57
|
+
faraday.basic_auth(options[:user], options[:password])
|
58
|
+
end
|
59
|
+
|
60
|
+
faraday.response :logger if options[:http_debug]
|
61
|
+
faraday.adapter Faraday.default_adapter
|
62
|
+
end
|
63
|
+
|
64
|
+
faraday.headers.merge!(HEADERS)
|
65
|
+
faraday.headers.merge!(optional_headers(options))
|
66
|
+
|
67
|
+
return faraday
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.faraday_ssl_options(options)
|
71
|
+
ssl = options[:ssl]
|
72
|
+
|
73
|
+
case ssl
|
74
|
+
when true
|
75
|
+
ssl = {verify: true}
|
76
|
+
|
77
|
+
when Hash
|
78
|
+
verify = ssl.fetch(:verify, true)
|
79
|
+
case verify
|
80
|
+
when true
|
81
|
+
# detailed SSL options. pass through to faraday
|
82
|
+
when nil, false
|
83
|
+
ssl = {verify: false}
|
84
|
+
else
|
85
|
+
raise ArgumentError, "Can't convert #{verify.class} of :verify option of :ssl option to true or false"
|
86
|
+
end
|
87
|
+
|
88
|
+
when nil, false
|
89
|
+
ssl = false
|
90
|
+
|
91
|
+
else
|
92
|
+
raise ArgumentError, "Can't convert #{ssl.class} of :ssl option to true, false, or Hash"
|
93
|
+
end
|
94
|
+
|
95
|
+
return ssl
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.optional_headers(options)
|
99
|
+
headers = {}
|
100
|
+
if v = options[:user]
|
101
|
+
headers[PrestoHeaders::PRESTO_USER] = v
|
102
|
+
end
|
103
|
+
if v = options[:source]
|
104
|
+
headers[PrestoHeaders::PRESTO_SOURCE] = v
|
105
|
+
end
|
106
|
+
if v = options[:catalog]
|
107
|
+
headers[PrestoHeaders::PRESTO_CATALOG] = v
|
108
|
+
end
|
109
|
+
if v = options[:schema]
|
110
|
+
headers[PrestoHeaders::PRESTO_SCHEMA] = v
|
111
|
+
end
|
112
|
+
if v = options[:time_zone]
|
113
|
+
headers[PrestoHeaders::PRESTO_TIME_ZONE] = v
|
114
|
+
end
|
115
|
+
if v = options[:language]
|
116
|
+
headers[PrestoHeaders::PRESTO_LANGUAGE] = v
|
117
|
+
end
|
118
|
+
if v = options[:properties]
|
119
|
+
headers[PrestoHeaders::PRESTO_SESSION] = encode_properties(v)
|
120
|
+
end
|
121
|
+
if options[:enable_x_msgpack]
|
122
|
+
# option name is enable_"x"_msgpack because "Accept: application/x-msgpack" header is
|
123
|
+
# not officially supported by Presto. We can use this option only if a proxy server
|
124
|
+
# decodes & encodes response body. Once this option is supported by Presto, option
|
125
|
+
# name should be enable_msgpack, which might be slightly different behavior.
|
126
|
+
headers['Accept'] = 'application/x-msgpack,application/json'
|
127
|
+
end
|
128
|
+
headers
|
129
|
+
end
|
130
|
+
|
131
|
+
HTTP11_SEPARATOR = ["(", ")", "<", ">", "@", ",", ";", ":", "\\", "<", ">", "/", "[", "]", "?", "=", "{", "}", " ", "\v"]
|
132
|
+
HTTP11_TOKEN_CHARSET = (32..126).map {|x| x.chr } - HTTP11_SEPARATOR
|
133
|
+
HTTP11_TOKEN_REGEXP = /^[#{Regexp.escape(HTTP11_TOKEN_CHARSET.join)}]+\z/
|
134
|
+
HTTP11_CTL_CHARSET = (0..31).map {|x| x.chr } + [127.chr]
|
135
|
+
HTTP11_CTL_CHARSET_REGEXP = /[#{Regexp.escape(HTTP11_CTL_CHARSET.join)}]/
|
136
|
+
|
137
|
+
def self.encode_properties(properties)
|
138
|
+
# this is a hack to set same header multiple times.
|
139
|
+
properties.map do |k, v|
|
140
|
+
token = k.to_s
|
141
|
+
field_value = v.to_s # TODO LWS encoding is not implemented
|
142
|
+
unless k =~ HTTP11_TOKEN_REGEXP
|
143
|
+
raise Faraday::ClientError, "Key of properties can't include HTTP/1.1 control characters or separators (#{HTTP11_SEPARATOR.map {|c| c =~ /\s/ ? c.dump : c }.join(' ')})"
|
144
|
+
end
|
145
|
+
if field_value =~ HTTP11_CTL_CHARSET_REGEXP
|
146
|
+
raise Faraday::ClientError, "Value of properties can't include HTTP/1.1 control characters"
|
147
|
+
end
|
148
|
+
"#{token}=#{field_value}"
|
149
|
+
end.join("\r\n#{PrestoHeaders::PRESTO_SESSION}: ")
|
150
|
+
end
|
151
|
+
|
152
|
+
private_class_method :faraday_ssl_options, :optional_headers, :encode_properties
|
153
|
+
|
154
|
+
end
|
data/lib/presto/client/query.rb
CHANGED
@@ -18,6 +18,7 @@ module Presto::Client
|
|
18
18
|
require 'faraday'
|
19
19
|
require 'presto/client/models'
|
20
20
|
require 'presto/client/errors'
|
21
|
+
require 'presto/client/faraday_client'
|
21
22
|
require 'presto/client/statement_client'
|
22
23
|
|
23
24
|
class Query
|
@@ -29,68 +30,18 @@ module Presto::Client
|
|
29
30
|
new StatementClient.new(faraday_client(options), nil, options, next_uri)
|
30
31
|
end
|
31
32
|
|
32
|
-
def self.
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
ssl = faraday_ssl_options(options)
|
39
|
-
|
40
|
-
if options[:password] && !ssl
|
41
|
-
raise ArgumentError, "Protocol must be https when passing a password"
|
42
|
-
end
|
43
|
-
|
44
|
-
url = "#{ssl ? "https" : "http"}://#{server}"
|
45
|
-
proxy = options[:http_proxy] || options[:proxy] # :proxy is obsoleted
|
46
|
-
|
47
|
-
faraday_options = {url: url, proxy: "#{proxy}"}
|
48
|
-
faraday_options[:ssl] = ssl if ssl
|
49
|
-
|
50
|
-
faraday = Faraday.new(faraday_options) do |faraday|
|
51
|
-
#faraday.request :url_encoded
|
52
|
-
|
53
|
-
if options[:user] && options[:password]
|
54
|
-
faraday.basic_auth(options[:user], options[:password])
|
55
|
-
end
|
56
|
-
|
57
|
-
faraday.response :logger if options[:http_debug]
|
58
|
-
faraday.adapter Faraday.default_adapter
|
33
|
+
def self.kill(query_id, options)
|
34
|
+
faraday = faraday_client(options)
|
35
|
+
response = faraday.delete do |req|
|
36
|
+
req.url "/v1/query/#{query_id}"
|
59
37
|
end
|
60
|
-
|
61
|
-
return faraday
|
38
|
+
return response.status / 100 == 2
|
62
39
|
end
|
63
40
|
|
64
|
-
def self.
|
65
|
-
|
66
|
-
|
67
|
-
case ssl
|
68
|
-
when true
|
69
|
-
ssl = {verify: true}
|
70
|
-
|
71
|
-
when Hash
|
72
|
-
verify = ssl.fetch(:verify, true)
|
73
|
-
case verify
|
74
|
-
when true
|
75
|
-
# detailed SSL options. pass through to faraday
|
76
|
-
when nil, false
|
77
|
-
ssl = {verify: false}
|
78
|
-
else
|
79
|
-
raise ArgumentError, "Can't convert #{verify.class} of :verify option of :ssl option to true or false"
|
80
|
-
end
|
81
|
-
|
82
|
-
when nil, false
|
83
|
-
ssl = false
|
84
|
-
|
85
|
-
else
|
86
|
-
raise ArgumentError, "Can't convert #{ssl.class} of :ssl option to true, false, or Hash"
|
87
|
-
end
|
88
|
-
|
89
|
-
return ssl
|
41
|
+
def self.faraday_client(options)
|
42
|
+
Presto::Client.faraday_client(options)
|
90
43
|
end
|
91
44
|
|
92
|
-
private_class_method :faraday_client, :faraday_ssl_options
|
93
|
-
|
94
45
|
def initialize(api)
|
95
46
|
@api = api
|
96
47
|
end
|
@@ -103,24 +54,29 @@ module Presto::Client
|
|
103
54
|
@api.advance
|
104
55
|
end
|
105
56
|
|
57
|
+
def advance_and_raise
|
58
|
+
cont = @api.advance
|
59
|
+
raise_if_failed
|
60
|
+
cont
|
61
|
+
end
|
62
|
+
|
106
63
|
def wait_for_columns
|
107
|
-
while @api.current_results.columns == nil &&
|
64
|
+
while @api.current_results.columns == nil && advance_and_raise
|
108
65
|
end
|
109
66
|
end
|
110
67
|
|
111
68
|
def wait_for_data
|
112
|
-
while @api.current_results.data == nil &&
|
69
|
+
while @api.current_results.data == nil && advance_and_raise
|
113
70
|
end
|
114
71
|
end
|
115
72
|
|
73
|
+
private :advance_and_raise
|
116
74
|
private :wait_for_columns
|
117
75
|
private :wait_for_data
|
118
76
|
|
119
77
|
def columns
|
120
78
|
wait_for_columns
|
121
79
|
|
122
|
-
raise_if_failed
|
123
|
-
|
124
80
|
return @api.current_results.columns
|
125
81
|
end
|
126
82
|
|
@@ -141,8 +97,6 @@ module Presto::Client
|
|
141
97
|
def each_row_chunk(&block)
|
142
98
|
wait_for_data
|
143
99
|
|
144
|
-
raise_if_failed
|
145
|
-
|
146
100
|
if self.columns == nil
|
147
101
|
raise PrestoError, "Query #{@api.current_results.id} has no columns"
|
148
102
|
end
|
@@ -151,7 +105,7 @@ module Presto::Client
|
|
151
105
|
if data = @api.current_results.data
|
152
106
|
block.call(data)
|
153
107
|
end
|
154
|
-
end while
|
108
|
+
end while advance_and_raise
|
155
109
|
end
|
156
110
|
|
157
111
|
def query_info
|
@@ -20,26 +20,7 @@ module Presto::Client
|
|
20
20
|
require 'presto/client/models'
|
21
21
|
require 'presto/client/errors'
|
22
22
|
|
23
|
-
module PrestoHeaders
|
24
|
-
PRESTO_USER = "X-Presto-User"
|
25
|
-
PRESTO_SOURCE = "X-Presto-Source"
|
26
|
-
PRESTO_CATALOG = "X-Presto-Catalog"
|
27
|
-
PRESTO_SCHEMA = "X-Presto-Schema"
|
28
|
-
PRESTO_TIME_ZONE = "X-Presto-Time-Zone"
|
29
|
-
PRESTO_LANGUAGE = "X-Presto-Language"
|
30
|
-
PRESTO_SESSION = "X-Presto-Session"
|
31
|
-
|
32
|
-
PRESTO_CURRENT_STATE = "X-Presto-Current-State"
|
33
|
-
PRESTO_MAX_WAIT = "X-Presto-Max-Wait"
|
34
|
-
PRESTO_MAX_SIZE = "X-Presto-Max-Size"
|
35
|
-
PRESTO_PAGE_SEQUENCE_ID = "X-Presto-Page-Sequence-Id"
|
36
|
-
end
|
37
|
-
|
38
23
|
class StatementClient
|
39
|
-
HEADERS = {
|
40
|
-
"User-Agent" => "presto-ruby/#{VERSION}",
|
41
|
-
}
|
42
|
-
|
43
24
|
# Presto can return too deep nested JSON
|
44
25
|
JSON_OPTIONS = {
|
45
26
|
:max_nesting => false
|
@@ -47,7 +28,6 @@ module Presto::Client
|
|
47
28
|
|
48
29
|
def initialize(faraday, query, options, next_uri=nil)
|
49
30
|
@faraday = faraday
|
50
|
-
@faraday.headers.merge!(HEADERS)
|
51
31
|
|
52
32
|
@options = options
|
53
33
|
@query = query
|
@@ -60,8 +40,6 @@ module Presto::Client
|
|
60
40
|
@models = Models
|
61
41
|
end
|
62
42
|
|
63
|
-
@faraday.headers.merge!(optional_headers)
|
64
|
-
|
65
43
|
if next_uri
|
66
44
|
response = faraday_get_with_retry(next_uri)
|
67
45
|
@results = @models::QueryResults.decode(parse_body(response))
|
@@ -70,41 +48,6 @@ module Presto::Client
|
|
70
48
|
end
|
71
49
|
end
|
72
50
|
|
73
|
-
def optional_headers
|
74
|
-
headers = {}
|
75
|
-
if v = @options[:user]
|
76
|
-
headers[PrestoHeaders::PRESTO_USER] = v
|
77
|
-
end
|
78
|
-
if v = @options[:source]
|
79
|
-
headers[PrestoHeaders::PRESTO_SOURCE] = v
|
80
|
-
end
|
81
|
-
if v = @options[:catalog]
|
82
|
-
headers[PrestoHeaders::PRESTO_CATALOG] = v
|
83
|
-
end
|
84
|
-
if v = @options[:schema]
|
85
|
-
headers[PrestoHeaders::PRESTO_SCHEMA] = v
|
86
|
-
end
|
87
|
-
if v = @options[:time_zone]
|
88
|
-
headers[PrestoHeaders::PRESTO_TIME_ZONE] = v
|
89
|
-
end
|
90
|
-
if v = @options[:language]
|
91
|
-
headers[PrestoHeaders::PRESTO_LANGUAGE] = v
|
92
|
-
end
|
93
|
-
if v = @options[:properties]
|
94
|
-
headers[PrestoHeaders::PRESTO_SESSION] = encode_properties(v)
|
95
|
-
end
|
96
|
-
if @options[:enable_x_msgpack]
|
97
|
-
# option name is enable_"x"_msgpack because "Accept: application/x-msgpack" header is
|
98
|
-
# not officially supported by Presto. We can use this option only if a proxy server
|
99
|
-
# decodes & encodes response body. Once this option is supported by Presto, option
|
100
|
-
# name should be enable_msgpack, which might be slightly different behavior.
|
101
|
-
headers['Accept'] = 'application/x-msgpack,application/json'
|
102
|
-
end
|
103
|
-
headers
|
104
|
-
end
|
105
|
-
|
106
|
-
private :optional_headers
|
107
|
-
|
108
51
|
def init_request(req)
|
109
52
|
req.options.timeout = @options[:http_timeout] || 300
|
110
53
|
req.options.open_timeout = @options[:http_open_timeout] || 60
|
@@ -185,6 +128,7 @@ module Presto::Client
|
|
185
128
|
begin
|
186
129
|
body_class.decode(hash)
|
187
130
|
rescue => e
|
131
|
+
body = JSON.dump(hash)
|
188
132
|
if body.size > 1024 + 3
|
189
133
|
body = "#{body[0, 1024]}..."
|
190
134
|
end
|
@@ -251,27 +195,6 @@ module Presto::Client
|
|
251
195
|
return false
|
252
196
|
end
|
253
197
|
|
254
|
-
HTTP11_SEPARATOR = ["(", ")", "<", ">", "@", ",", ";", ":", "\\", "<", ">", "/", "[", "]", "?", "=", "{", "}", " ", "\v"]
|
255
|
-
HTTP11_TOKEN_CHARSET = (32..126).map {|x| x.chr } - HTTP11_SEPARATOR
|
256
|
-
HTTP11_TOKEN_REGEXP = /^[#{Regexp.escape(HTTP11_TOKEN_CHARSET.join)}]+\z/
|
257
|
-
HTTP11_CTL_CHARSET = (0..31).map {|x| x.chr } + [127.chr]
|
258
|
-
HTTP11_CTL_CHARSET_REGEXP = /[#{Regexp.escape(HTTP11_CTL_CHARSET.join)}]/
|
259
|
-
|
260
|
-
def encode_properties(properties)
|
261
|
-
# this is a hack to set same header multiple times.
|
262
|
-
properties.map do |k, v|
|
263
|
-
token = k.to_s
|
264
|
-
field_value = v.to_s # TODO LWS encoding is not implemented
|
265
|
-
unless k =~ HTTP11_TOKEN_REGEXP
|
266
|
-
raise Faraday::ClientError, "Key of properties can't include HTTP/1.1 control characters or separators (#{HTTP11_SEPARATOR.map {|c| c =~ /\s/ ? c.dump : c }.join(' ')})"
|
267
|
-
end
|
268
|
-
if field_value =~ HTTP11_CTL_CHARSET_REGEXP
|
269
|
-
raise Faraday::ClientError, "Value of properties can't include HTTP/1.1 control characters"
|
270
|
-
end
|
271
|
-
"#{token}=#{field_value}"
|
272
|
-
end.join("\r\n#{PrestoHeaders::PRESTO_SESSION}: ")
|
273
|
-
end
|
274
|
-
|
275
198
|
def close
|
276
199
|
return if @closed
|
277
200
|
|
@@ -25,6 +25,10 @@ describe Presto::Client::StatementClient do
|
|
25
25
|
}
|
26
26
|
end
|
27
27
|
|
28
|
+
let :faraday do
|
29
|
+
Presto::Client.faraday_client(options)
|
30
|
+
end
|
31
|
+
|
28
32
|
it "sets headers" do
|
29
33
|
stub_request(:post, "localhost/v1/statement").
|
30
34
|
with(body: query,
|
@@ -38,7 +42,6 @@ describe Presto::Client::StatementClient do
|
|
38
42
|
"X-Presto-Session" => options[:properties].map {|k,v| "#{k}=#{v}"}.join("\r\nX-Presto-Session: ")
|
39
43
|
}).to_return(body: response_json.to_json)
|
40
44
|
|
41
|
-
faraday = Faraday.new(url: "http://localhost")
|
42
45
|
StatementClient.new(faraday, query, options)
|
43
46
|
end
|
44
47
|
|
@@ -75,7 +78,6 @@ describe Presto::Client::StatementClient do
|
|
75
78
|
"X-Presto-Session" => options[:properties].map {|k,v| "#{k}=#{v}"}.join("\r\nX-Presto-Session: ")
|
76
79
|
}).to_return(body: lambda{|req|if retry_p; response_json.to_json; else; retry_p=true; raise Timeout::Error.new("execution expired"); end })
|
77
80
|
|
78
|
-
faraday = Faraday.new(url: "http://localhost")
|
79
81
|
sc = StatementClient.new(faraday, query, options.merge(http_open_timeout: 1))
|
80
82
|
sc.has_next?.should be_true
|
81
83
|
sc.advance.should be_true
|
@@ -109,8 +111,8 @@ describe Presto::Client::StatementClient do
|
|
109
111
|
"Accept" => "application/x-msgpack,application/json"
|
110
112
|
}).to_return(body: lambda{|req|if retry_p; MessagePack.dump(response_json); else; retry_p=true; raise Timeout::Error.new("execution expired"); end }, headers: {"Content-Type" => "application/x-msgpack"})
|
111
113
|
|
112
|
-
|
113
|
-
sc = StatementClient.new(faraday, query, options
|
114
|
+
options.merge!(http_open_timeout: 1, enable_x_msgpack: "application/x-msgpack")
|
115
|
+
sc = StatementClient.new(faraday, query, options)
|
114
116
|
sc.has_next?.should be_true
|
115
117
|
sc.advance.should be_true
|
116
118
|
retry_p.should be_true
|
@@ -136,6 +138,54 @@ describe Presto::Client::StatementClient do
|
|
136
138
|
end.should raise_error(TypeError, /String to Hash/)
|
137
139
|
end
|
138
140
|
|
141
|
+
describe '#query_info' do
|
142
|
+
it "raises an exception with sample JSON if response is unexpected" do
|
143
|
+
headers = {
|
144
|
+
"User-Agent" => "presto-ruby/#{VERSION}",
|
145
|
+
"X-Presto-Catalog" => options[:catalog],
|
146
|
+
"X-Presto-Schema" => options[:schema],
|
147
|
+
"X-Presto-User" => options[:user],
|
148
|
+
"X-Presto-Language" => options[:language],
|
149
|
+
"X-Presto-Time-Zone" => options[:time_zone],
|
150
|
+
"X-Presto-Session" => options[:properties].map {|k,v| "#{k}=#{v}"}.join("\r\nX-Presto-Session: ")
|
151
|
+
}
|
152
|
+
|
153
|
+
stub_request(:post, "http://localhost/v1/statement").
|
154
|
+
with(body: query, headers: headers).
|
155
|
+
to_return(body: response_json2.to_json)
|
156
|
+
|
157
|
+
sc = StatementClient.new(faraday, query, options)
|
158
|
+
|
159
|
+
stub_request(:get, "http://localhost/v1/query/#{response_json2[:id]}").
|
160
|
+
with(headers: headers).
|
161
|
+
to_return(body: {"session" => "invalid session structure"}.to_json)
|
162
|
+
|
163
|
+
lambda do
|
164
|
+
sc.query_info
|
165
|
+
end.should raise_error(PrestoHttpError, /Presto API returned unexpected structure at \/v1\/query\/queryid\. Expected Presto::Client::ModelVersions::.*::QueryInfo but got {"session":"invalid session structure"}/)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
describe "Killing a query" do
|
170
|
+
let(:query_id) { 'A_QUERY_ID' }
|
171
|
+
|
172
|
+
it "sends DELETE request with empty body to /v1/query/{queryId}" do
|
173
|
+
stub_request(:delete, "http://localhost/v1/query/#{query_id}").
|
174
|
+
with(body: "",
|
175
|
+
headers: {
|
176
|
+
"User-Agent" => "presto-ruby/#{VERSION}",
|
177
|
+
"X-Presto-Catalog" => options[:catalog],
|
178
|
+
"X-Presto-Schema" => options[:schema],
|
179
|
+
"X-Presto-User" => options[:user],
|
180
|
+
"X-Presto-Language" => options[:language],
|
181
|
+
"X-Presto-Time-Zone" => options[:time_zone],
|
182
|
+
"X-Presto-Session" => options[:properties].map {|k,v| "#{k}=#{v}"}.join("\r\nX-Presto-Session: "),
|
183
|
+
}).to_return(body: {}.to_json)
|
184
|
+
|
185
|
+
Presto::Client.new(options).kill(query_id)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
139
189
|
describe 'HTTP basic auth' do
|
140
190
|
let(:password) { 'abcd' }
|
141
191
|
|
@@ -154,7 +204,7 @@ describe Presto::Client::StatementClient do
|
|
154
204
|
basic_auth: [options[:user], password]
|
155
205
|
).to_return(body: response_json.to_json)
|
156
206
|
|
157
|
-
|
207
|
+
options.merge!(ssl: { verify: true }, password: password)
|
158
208
|
StatementClient.new(faraday, query, options)
|
159
209
|
end
|
160
210
|
|
@@ -289,7 +339,6 @@ describe Presto::Client::StatementClient do
|
|
289
339
|
"X-Presto-Session" => options[:properties].map {|k,v| "#{k}=#{v}"}.join("\r\nX-Presto-Session: ")
|
290
340
|
}).to_return(body: nested_json.to_json(:max_nesting => false))
|
291
341
|
|
292
|
-
faraday = Faraday.new(url: "http://localhost")
|
293
342
|
StatementClient.new(faraday, query, options)
|
294
343
|
end
|
295
344
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: presto-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sadayuki Furuhashi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-11-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -131,6 +131,7 @@ files:
|
|
131
131
|
- lib/presto/client.rb
|
132
132
|
- lib/presto/client/client.rb
|
133
133
|
- lib/presto/client/errors.rb
|
134
|
+
- lib/presto/client/faraday_client.rb
|
134
135
|
- lib/presto/client/model_versions/0.149.rb
|
135
136
|
- lib/presto/client/model_versions/0.153.rb
|
136
137
|
- lib/presto/client/model_versions/0.173.rb
|
@@ -168,7 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
168
169
|
version: '0'
|
169
170
|
requirements: []
|
170
171
|
rubyforge_project:
|
171
|
-
rubygems_version: 2.6.
|
172
|
+
rubygems_version: 2.6.13
|
172
173
|
signing_key:
|
173
174
|
specification_version: 4
|
174
175
|
summary: Presto client library
|