presto-client 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/ChangeLog +13 -0
- data/README.md +19 -12
- data/lib/presto/client/client.rb +24 -2
- data/lib/presto/client/errors.rb +42 -0
- data/lib/presto/client/models.rb +142 -70
- data/lib/presto/client/query.rb +36 -6
- data/lib/presto/client/statement_client.rb +16 -10
- data/lib/presto/client/version.rb +1 -1
- data/presto-client.gemspec +1 -1
- metadata +7 -5
- data/Gemfile.lock +0 -38
data/.gitignore
ADDED
data/ChangeLog
ADDED
data/README.md
CHANGED
@@ -10,25 +10,32 @@ This is a client library for Ruby to run queries on Presto.
|
|
10
10
|
```ruby
|
11
11
|
require 'presto-client'
|
12
12
|
|
13
|
-
# create a client object
|
14
|
-
client =
|
13
|
+
# create a client object:
|
14
|
+
client = Presto::Client.new(
|
15
15
|
server: "localhost:8880",
|
16
16
|
user: "frsyuki",
|
17
17
|
catalog: "native",
|
18
18
|
schema: "default",
|
19
19
|
)
|
20
20
|
|
21
|
-
#
|
22
|
-
|
23
|
-
|
24
|
-
# wait for completion and get columns
|
25
|
-
q.columns.each {|column|
|
26
|
-
puts "column: #{column.name}.#{column.type}"
|
27
|
-
}
|
28
|
-
|
29
|
-
# get query results
|
30
|
-
q.each_row {|row|
|
21
|
+
# run a query and get results:
|
22
|
+
columns, rows = client.run("select * from sys.node")
|
23
|
+
rows.each {|row|
|
31
24
|
p row
|
32
25
|
}
|
26
|
+
|
27
|
+
# another way to run a query and fetch results streamingly:
|
28
|
+
# start running a query on presto
|
29
|
+
client.query("select * from sys.node") do |q|
|
30
|
+
# wait for completion and get columns
|
31
|
+
q.columns.each {|column|
|
32
|
+
puts "column: #{column.name}.#{column.type}"
|
33
|
+
}
|
34
|
+
|
35
|
+
# get query results
|
36
|
+
q.each_row {|row|
|
37
|
+
p row
|
38
|
+
}
|
39
|
+
end
|
33
40
|
```
|
34
41
|
|
data/lib/presto/client/client.rb
CHANGED
@@ -23,8 +23,30 @@ module Presto::Client
|
|
23
23
|
@session = ClientSession.new(options)
|
24
24
|
end
|
25
25
|
|
26
|
-
def query(query)
|
27
|
-
|
26
|
+
def query(query, &block)
|
27
|
+
if block
|
28
|
+
q = Query.start(@session, query)
|
29
|
+
begin
|
30
|
+
yield q
|
31
|
+
ensure
|
32
|
+
q.close
|
33
|
+
end
|
34
|
+
else
|
35
|
+
return Query.start(@session, query)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def run(query)
|
40
|
+
q = Query.start(@session, query)
|
41
|
+
begin
|
42
|
+
columns = q.columns
|
43
|
+
if columns.empty?
|
44
|
+
return [], []
|
45
|
+
end
|
46
|
+
return columns, q.rows
|
47
|
+
ensure
|
48
|
+
q.close
|
49
|
+
end
|
28
50
|
end
|
29
51
|
end
|
30
52
|
|
@@ -0,0 +1,42 @@
|
|
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
|
+
class PrestoError < StandardError
|
18
|
+
end
|
19
|
+
|
20
|
+
class PrestoHttpError < PrestoError
|
21
|
+
def initialize(status, message)
|
22
|
+
super(message)
|
23
|
+
@status = status
|
24
|
+
end
|
25
|
+
|
26
|
+
attr_reader :status
|
27
|
+
end
|
28
|
+
|
29
|
+
class PrestoClientError < PrestoError
|
30
|
+
end
|
31
|
+
|
32
|
+
class PrestoQueryError < PrestoError
|
33
|
+
def initialize(message, query_id, error_code, failure_info)
|
34
|
+
super(message)
|
35
|
+
@query_id = query_id
|
36
|
+
@error_code = error_code
|
37
|
+
@failure_info = failure_info
|
38
|
+
end
|
39
|
+
|
40
|
+
attr_reader :error_code, :failure_info
|
41
|
+
end
|
42
|
+
end
|
data/lib/presto/client/models.rb
CHANGED
@@ -53,58 +53,58 @@ module Presto::Client
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
56
|
+
class StageStats
|
57
|
+
attr_reader :stage_id
|
58
|
+
attr_reader :state
|
59
|
+
attr_reader :done
|
60
|
+
attr_reader :nodes
|
61
|
+
attr_reader :total_splits
|
62
|
+
attr_reader :queued_splits
|
63
|
+
attr_reader :running_splits
|
64
|
+
attr_reader :completed_splits
|
65
|
+
attr_reader :user_time_millis
|
66
|
+
attr_reader :cpu_time_millis
|
67
|
+
attr_reader :wall_time_millis
|
68
|
+
attr_reader :processed_rows
|
69
|
+
attr_reader :processed_bytes
|
70
|
+
attr_reader :sub_stages
|
71
|
+
|
72
|
+
def initialize(options={})
|
73
|
+
@stage_id = options[:stage_id]
|
74
|
+
@state = options[:state]
|
75
|
+
@done = options[:done]
|
76
|
+
@nodes = options[:nodes]
|
77
|
+
@total_splits = options[:total_splits]
|
78
|
+
@queued_splits = options[:queued_splits]
|
79
|
+
@running_splits = options[:running_splits]
|
80
|
+
@completed_splits = options[:completed_splits]
|
81
|
+
@user_time_millis = options[:user_time_millis]
|
82
|
+
@cpu_time_millis = options[:cpu_time_millis]
|
83
|
+
@wall_time_millis = options[:wall_time_millis]
|
84
|
+
@processed_rows = options[:processed_rows]
|
85
|
+
@processed_bytes = options[:processed_bytes]
|
86
|
+
@sub_stages = options[:sub_stages]
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.decode_hash(hash)
|
90
|
+
new(
|
91
|
+
stage_id: hash["stageId"],
|
92
|
+
state: hash["state"],
|
93
|
+
done: hash["done"],
|
94
|
+
nodes: hash["nodes"],
|
95
|
+
total_splits: hash["totalSplits"],
|
96
|
+
queued_splits: hash["queuedSplits"],
|
97
|
+
running_splits: hash["runningSplits"],
|
98
|
+
completed_splits: hash["completedSplits"],
|
99
|
+
user_time_millis: hash["userTimeMillis"],
|
100
|
+
cpu_time_millis: hash["cpuTimeMillis"],
|
101
|
+
wall_time_millis: hash["wallTimeMillis"],
|
102
|
+
processed_rows: hash["processedRows"],
|
103
|
+
processed_bytes: hash["processedBytes"],
|
104
|
+
sub_stages: hash["subStages"] && hash["subStages"].map {|h| StageStats.decode_hash(h) },
|
105
|
+
)
|
106
|
+
end
|
107
|
+
end
|
108
108
|
|
109
109
|
class StatementStats
|
110
110
|
attr_reader :state
|
@@ -119,22 +119,22 @@ module Presto::Client
|
|
119
119
|
attr_reader :wall_time_millis
|
120
120
|
attr_reader :processed_rows
|
121
121
|
attr_reader :processed_bytes
|
122
|
-
|
122
|
+
attr_reader :root_stage
|
123
123
|
|
124
124
|
def initialize(options={})
|
125
|
-
@state = state
|
126
|
-
@scheduled = scheduled
|
127
|
-
@nodes = nodes
|
128
|
-
@total_splits = total_splits
|
129
|
-
@queued_splits = queued_splits
|
130
|
-
@running_splits = running_splits
|
131
|
-
@completed_splits = completed_splits
|
132
|
-
@user_time_millis = user_time_millis
|
133
|
-
@cpu_time_millis = cpu_time_millis
|
134
|
-
@wall_time_millis = wall_time_millis
|
135
|
-
@processed_rows = processed_rows
|
136
|
-
@processed_bytes = processed_bytes
|
137
|
-
|
125
|
+
@state = options[:state]
|
126
|
+
@scheduled = options[:scheduled]
|
127
|
+
@nodes = options[:nodes]
|
128
|
+
@total_splits = options[:total_splits]
|
129
|
+
@queued_splits = options[:queued_splits]
|
130
|
+
@running_splits = options[:running_splits]
|
131
|
+
@completed_splits = options[:completed_splits]
|
132
|
+
@user_time_millis = options[:user_time_millis]
|
133
|
+
@cpu_time_millis = options[:cpu_time_millis]
|
134
|
+
@wall_time_millis = options[:wall_time_millis]
|
135
|
+
@processed_rows = options[:processed_rows]
|
136
|
+
@processed_bytes = options[:processed_bytes]
|
137
|
+
@root_stage = options[:root_stage]
|
138
138
|
end
|
139
139
|
|
140
140
|
def self.decode_hash(hash)
|
@@ -151,7 +151,79 @@ module Presto::Client
|
|
151
151
|
wall_time_millis: hash["wallTimeMillis"],
|
152
152
|
processed_rows: hash["processedRows"],
|
153
153
|
processed_bytes: hash["processedBytes"],
|
154
|
-
|
154
|
+
root_stage: hash["rootStage"] && StageStats.decode_hash(hash["rootStage"]),
|
155
|
+
)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
class ErrorLocation
|
160
|
+
attr_reader :line_number
|
161
|
+
attr_reader :column_number
|
162
|
+
|
163
|
+
def initialize(options={})
|
164
|
+
@line_number = options[:line_number]
|
165
|
+
@column_number = options[:column_number]
|
166
|
+
end
|
167
|
+
|
168
|
+
def self.decode_hash(hash)
|
169
|
+
new(
|
170
|
+
line_number: hash["lineNumber"],
|
171
|
+
column_number: hash["columnNumber"],
|
172
|
+
)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
class FailureInfo
|
177
|
+
attr_reader :type
|
178
|
+
attr_reader :message
|
179
|
+
attr_reader :cause
|
180
|
+
attr_reader :suppressed
|
181
|
+
attr_reader :stack
|
182
|
+
attr_reader :error_location
|
183
|
+
|
184
|
+
def initialize(options={})
|
185
|
+
@type = options[:type]
|
186
|
+
@message = options[:message]
|
187
|
+
@cause = options[:cause]
|
188
|
+
@suppressed = options[:suppressed]
|
189
|
+
@stack = options[:stack]
|
190
|
+
@error_location = options[:error_location]
|
191
|
+
end
|
192
|
+
|
193
|
+
def self.decode_hash(hash)
|
194
|
+
new(
|
195
|
+
type: hash["type"],
|
196
|
+
message: hash["message"],
|
197
|
+
cause: hash["cause"],
|
198
|
+
suppressed: hash["suppressed"] && hash["suppressed"].map {|h| FailureInfo.decode_hash(h) },
|
199
|
+
stack: hash["stack"],
|
200
|
+
error_location: hash["errorLocation"] && ErrorLocation.decode_hash(hash["errorLocation"]),
|
201
|
+
)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
class QueryError
|
206
|
+
attr_reader :message
|
207
|
+
attr_reader :sql_state
|
208
|
+
attr_reader :error_code
|
209
|
+
attr_reader :error_location
|
210
|
+
attr_reader :failure_info
|
211
|
+
|
212
|
+
def initialize(options={})
|
213
|
+
@message = options[:message]
|
214
|
+
@sql_state = options[:sql_state]
|
215
|
+
@error_code = options[:error_code]
|
216
|
+
@error_location = options[:error_location]
|
217
|
+
@failure_info = options[:failure_info]
|
218
|
+
end
|
219
|
+
|
220
|
+
def self.decode_hash(hash)
|
221
|
+
new(
|
222
|
+
message: hash["message"],
|
223
|
+
sql_state: hash["sqlState"],
|
224
|
+
error_code: hash["errorCode"],
|
225
|
+
error_location: hash["errorLocation"] && ErrorLocation.decode_hash(hash["errorLocation"]),
|
226
|
+
failure_info: hash["failureInfo"] && FailureInfo.decode_hash(hash["failureInfo"]),
|
155
227
|
)
|
156
228
|
end
|
157
229
|
end
|
@@ -183,10 +255,10 @@ module Presto::Client
|
|
183
255
|
info_uri: hash["infoUri"],
|
184
256
|
partial_cache_uri: hash["partialCancelUri"],
|
185
257
|
next_uri: hash["nextUri"],
|
186
|
-
columns: hash["columns"]
|
258
|
+
columns: hash["columns"] && hash["columns"].map {|h| Column.decode_hash(h) },
|
187
259
|
data: hash["data"],
|
188
|
-
stats: StatementStats.decode_hash(hash["stats"]),
|
189
|
-
error: hash["error"],
|
260
|
+
stats: hash["stats"] && StatementStats.decode_hash(hash["stats"]),
|
261
|
+
error: hash["error"] && QueryError.decode_hash(hash["error"]),
|
190
262
|
)
|
191
263
|
end
|
192
264
|
end
|
data/lib/presto/client/query.rb
CHANGED
@@ -17,6 +17,7 @@ module Presto::Client
|
|
17
17
|
|
18
18
|
require 'faraday'
|
19
19
|
require 'presto/client/models'
|
20
|
+
require 'presto/client/errors'
|
20
21
|
require 'presto/client/statement_client'
|
21
22
|
|
22
23
|
class Query
|
@@ -34,6 +35,8 @@ module Presto::Client
|
|
34
35
|
@client = client
|
35
36
|
end
|
36
37
|
|
38
|
+
attr_reader :client
|
39
|
+
|
37
40
|
def wait_for_data
|
38
41
|
while @client.has_next? && @client.current_results.data == nil
|
39
42
|
@client.advance
|
@@ -50,32 +53,59 @@ module Presto::Client
|
|
50
53
|
return @client.current_results.columns
|
51
54
|
end
|
52
55
|
|
56
|
+
def rows
|
57
|
+
rows = []
|
58
|
+
each_row_chunk {|chunk|
|
59
|
+
rows.concat(chunk)
|
60
|
+
}
|
61
|
+
return rows
|
62
|
+
end
|
63
|
+
|
53
64
|
def each_row(&block)
|
65
|
+
each_row_chunk {|chunk|
|
66
|
+
chunk.each(&block)
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
def each_row_chunk(&block)
|
54
71
|
wait_for_data
|
55
72
|
|
56
73
|
raise_error unless @client.query_succeeded?
|
57
74
|
|
58
75
|
if self.columns == nil
|
59
|
-
raise "Query #{@client.current_results.id} has no columns"
|
76
|
+
raise PrestoError, "Query #{@client.current_results.id} has no columns"
|
60
77
|
end
|
61
78
|
|
62
79
|
begin
|
63
80
|
if data = @client.current_results.data
|
64
|
-
|
81
|
+
block.call(data)
|
65
82
|
end
|
66
83
|
@client.advance
|
67
84
|
end while @client.has_next?
|
68
85
|
end
|
69
86
|
|
87
|
+
def cancel
|
88
|
+
@client.cancel_leaf_stage
|
89
|
+
end
|
90
|
+
|
91
|
+
def close
|
92
|
+
@client.cancel_leaf_stage
|
93
|
+
nil
|
94
|
+
end
|
95
|
+
|
70
96
|
def raise_error
|
71
97
|
if @client.closed?
|
72
|
-
raise "Query aborted by user"
|
98
|
+
raise PrestoClientError, "Query aborted by user"
|
73
99
|
elsif @client.exception?
|
74
|
-
|
100
|
+
# query is gone
|
101
|
+
raise @client.exception
|
75
102
|
elsif @client.query_failed?
|
76
103
|
results = @client.current_results
|
77
|
-
|
78
|
-
|
104
|
+
error = results.error
|
105
|
+
unless error
|
106
|
+
raise PrestoQueryError.new("Query #{results.id} failed: (unknown reason)", results.id, nil, nil)
|
107
|
+
end
|
108
|
+
raise PrestoQueryError.new("Query #{results.id} failed: #{error.message}", results.id, error.error_code, error.failure_info)
|
79
109
|
end
|
80
110
|
end
|
81
111
|
|
@@ -17,6 +17,7 @@ module Presto::Client
|
|
17
17
|
|
18
18
|
require 'multi_json'
|
19
19
|
require 'presto/client/models'
|
20
|
+
require 'presto/client/errors'
|
20
21
|
|
21
22
|
module PrestoHeaders
|
22
23
|
PRESTO_USER = "X-Presto-User"
|
@@ -68,7 +69,7 @@ module Presto::Client
|
|
68
69
|
|
69
70
|
# TODO error handling
|
70
71
|
if response.status != 200
|
71
|
-
raise "Failed to start query: #{response.body}"
|
72
|
+
raise PrestoHttpError.new(response.status, "Failed to start query: #{response.body}")
|
72
73
|
end
|
73
74
|
|
74
75
|
body = response.body
|
@@ -136,7 +137,7 @@ module Presto::Client
|
|
136
137
|
|
137
138
|
if response.status != 503 # retry on 503 Service Unavailable
|
138
139
|
# deterministic error
|
139
|
-
@exception =
|
140
|
+
@exception = PrestoHttpError.new(response.status, "Error fetching next at #{uri} returned #{response.status}: #{response.body}")
|
140
141
|
raise @exception
|
141
142
|
end
|
142
143
|
|
@@ -144,21 +145,26 @@ module Presto::Client
|
|
144
145
|
sleep attempts * 0.1
|
145
146
|
end while (Time.now - start) < 2*60*60 && !@closed
|
146
147
|
|
147
|
-
@exception =
|
148
|
+
@exception = PrestoHttpError.new(408, "Error fetching next due to timeout")
|
148
149
|
raise @exception
|
149
150
|
end
|
150
151
|
|
151
|
-
def
|
152
|
-
return if @closed
|
153
|
-
|
154
|
-
# cancel running statement
|
152
|
+
def cancel_leaf_stage
|
155
153
|
if uri = @results.next_uri
|
156
|
-
|
157
|
-
# TODO make async reqeust and ignore response
|
158
|
-
@faraday.delete do |req|
|
154
|
+
response = @faraday.delete do |req|
|
159
155
|
req.url uri
|
160
156
|
end
|
157
|
+
return response.status / 100 == 2
|
161
158
|
end
|
159
|
+
return false
|
160
|
+
end
|
161
|
+
|
162
|
+
def close
|
163
|
+
return if @closed
|
164
|
+
|
165
|
+
# cancel running statement
|
166
|
+
# TODO make async reqeust and ignore response?
|
167
|
+
cancel_leaf_stage
|
162
168
|
|
163
169
|
@closed = true
|
164
170
|
nil
|
data/presto-client.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.require_paths = ["lib"]
|
18
18
|
gem.has_rdoc = false
|
19
19
|
|
20
|
-
gem.required_ruby_version = ">= 1.9.
|
20
|
+
gem.required_ruby_version = ">= 1.9.1"
|
21
21
|
|
22
22
|
gem.add_dependency "faraday", ["~> 0.8.8"]
|
23
23
|
gem.add_dependency "multi_json", ["~> 1.0"]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: presto-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-01-
|
12
|
+
date: 2014-01-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: faraday
|
@@ -98,13 +98,15 @@ executables: []
|
|
98
98
|
extensions: []
|
99
99
|
extra_rdoc_files: []
|
100
100
|
files:
|
101
|
+
- .gitignore
|
102
|
+
- ChangeLog
|
101
103
|
- Gemfile
|
102
|
-
- Gemfile.lock
|
103
104
|
- README.md
|
104
105
|
- Rakefile
|
105
106
|
- lib/presto-client.rb
|
106
107
|
- lib/presto/client.rb
|
107
108
|
- lib/presto/client/client.rb
|
109
|
+
- lib/presto/client/errors.rb
|
108
110
|
- lib/presto/client/models.rb
|
109
111
|
- lib/presto/client/query.rb
|
110
112
|
- lib/presto/client/statement_client.rb
|
@@ -125,7 +127,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
125
127
|
requirements:
|
126
128
|
- - ! '>='
|
127
129
|
- !ruby/object:Gem::Version
|
128
|
-
version: 1.9.
|
130
|
+
version: 1.9.1
|
129
131
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
132
|
none: false
|
131
133
|
requirements:
|
@@ -134,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
134
136
|
version: '0'
|
135
137
|
segments:
|
136
138
|
- 0
|
137
|
-
hash:
|
139
|
+
hash: 453544593424709681
|
138
140
|
requirements: []
|
139
141
|
rubyforge_project:
|
140
142
|
rubygems_version: 1.8.23
|
data/Gemfile.lock
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
presto-client (0.1.0)
|
5
|
-
faraday (~> 0.8.8)
|
6
|
-
multi_json (~> 1.0)
|
7
|
-
|
8
|
-
GEM
|
9
|
-
remote: https://rubygems.org/
|
10
|
-
specs:
|
11
|
-
addressable (2.3.5)
|
12
|
-
crack (0.3.2)
|
13
|
-
diff-lcs (1.2.4)
|
14
|
-
faraday (0.8.8)
|
15
|
-
multipart-post (~> 1.2.0)
|
16
|
-
multi_json (1.8.2)
|
17
|
-
multipart-post (1.2.0)
|
18
|
-
rake (10.1.1)
|
19
|
-
rspec (2.13.0)
|
20
|
-
rspec-core (~> 2.13.0)
|
21
|
-
rspec-expectations (~> 2.13.0)
|
22
|
-
rspec-mocks (~> 2.13.0)
|
23
|
-
rspec-core (2.13.1)
|
24
|
-
rspec-expectations (2.13.0)
|
25
|
-
diff-lcs (>= 1.1.3, < 2.0)
|
26
|
-
rspec-mocks (2.13.1)
|
27
|
-
webmock (1.16.1)
|
28
|
-
addressable (>= 2.2.7)
|
29
|
-
crack (>= 0.3.2)
|
30
|
-
|
31
|
-
PLATFORMS
|
32
|
-
ruby
|
33
|
-
|
34
|
-
DEPENDENCIES
|
35
|
-
presto-client!
|
36
|
-
rake (>= 0.9.2)
|
37
|
-
rspec (~> 2.13.0)
|
38
|
-
webmock (~> 1.16.1)
|