td-client 0.8.58 → 0.8.59
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.
- data/lib/td/client.rb +5 -5
- data/lib/td/client/api.rb +40 -20
- data/lib/td/client/model.rb +13 -7
- data/lib/td/client/version.rb +1 -1
- data/spec/td/client/api_spec.rb +105 -20
- metadata +4 -4
data/lib/td/client.rb
CHANGED
|
@@ -137,16 +137,16 @@ class Client
|
|
|
137
137
|
# => [Job]
|
|
138
138
|
def jobs(from=nil, to=nil, status=nil, conditions=nil)
|
|
139
139
|
result = @api.list_jobs(from, to, status, conditions)
|
|
140
|
-
result.map {|job_id,type,status,query,start_at,end_at,result_url,priority,retry_limit,org,db|
|
|
141
|
-
Job.new(self, job_id, type, query, status, nil, nil, start_at, end_at, nil, result_url, nil, priority, retry_limit, org, db)
|
|
140
|
+
result.map {|job_id, type, status, query, start_at, end_at, cpu_time, result_url, priority, retry_limit, org, db|
|
|
141
|
+
Job.new(self, job_id, type, query, status, nil, nil, start_at, end_at, cpu_time, nil, result_url, nil, priority, retry_limit, org, db)
|
|
142
142
|
}
|
|
143
143
|
end
|
|
144
144
|
|
|
145
145
|
# => Job
|
|
146
146
|
def job(job_id)
|
|
147
147
|
job_id = job_id.to_s
|
|
148
|
-
type, query, status, url, debug, start_at, end_at, result_url, hive_result_schema, priority, retry_limit, org, db = @api.show_job(job_id)
|
|
149
|
-
Job.new(self, job_id, type, query, status, url, debug, start_at, end_at, nil, result_url, hive_result_schema, priority, retry_limit, org, db)
|
|
148
|
+
type, query, status, url, debug, start_at, end_at, cpu_time, result_url, hive_result_schema, priority, retry_limit, org, db = @api.show_job(job_id)
|
|
149
|
+
Job.new(self, job_id, type, query, status, url, debug, start_at, end_at, cpu_time, nil, result_url, hive_result_schema, priority, retry_limit, org, db)
|
|
150
150
|
end
|
|
151
151
|
|
|
152
152
|
# => status:String
|
|
@@ -227,7 +227,7 @@ class Client
|
|
|
227
227
|
data = @api.show_bulk_import(name)
|
|
228
228
|
BulkImport.new(self, data)
|
|
229
229
|
end
|
|
230
|
-
|
|
230
|
+
|
|
231
231
|
# => [BulkImport]
|
|
232
232
|
def bulk_imports
|
|
233
233
|
@api.list_bulk_imports.map {|data|
|
data/lib/td/client/api.rb
CHANGED
|
@@ -6,6 +6,9 @@ module TreasureData
|
|
|
6
6
|
class APIError < StandardError
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
+
class ParameterValidationError < StandardError
|
|
10
|
+
end
|
|
11
|
+
|
|
9
12
|
class AuthError < APIError
|
|
10
13
|
end
|
|
11
14
|
|
|
@@ -101,39 +104,44 @@ class API
|
|
|
101
104
|
record.to_msgpack(out)
|
|
102
105
|
end
|
|
103
106
|
|
|
104
|
-
def self.
|
|
107
|
+
def self.validate_name(target, min_len, max_len, name)
|
|
108
|
+
if !target.instance_of?(String) || target.empty?
|
|
109
|
+
raise ParameterValidationError,
|
|
110
|
+
"A valid target name is required"
|
|
111
|
+
end
|
|
112
|
+
|
|
105
113
|
name = name.to_s
|
|
106
114
|
if name.empty?
|
|
107
|
-
raise
|
|
115
|
+
raise ParameterValidationError,
|
|
116
|
+
"Empty #{target} name is not allowed"
|
|
108
117
|
end
|
|
109
|
-
if name.length <
|
|
110
|
-
raise
|
|
118
|
+
if name.length < min_len || name.length > max_len
|
|
119
|
+
raise ParameterValidationError,
|
|
120
|
+
"#{target.capitalize} name must be between #{min_len} and #{max_len} characters long. Got #{name.length} " +
|
|
121
|
+
(name.length == 1 ? "character" : "characters") + "."
|
|
111
122
|
end
|
|
112
123
|
unless name =~ /^([a-z0-9_]+)$/
|
|
113
|
-
raise
|
|
124
|
+
raise ParameterValidationError,
|
|
125
|
+
"#{target.capitalize} name must only consist of lower-case alpha-numeric characters and '_'."
|
|
114
126
|
end
|
|
127
|
+
|
|
115
128
|
name
|
|
116
129
|
end
|
|
117
130
|
|
|
131
|
+
def self.validate_database_name(name)
|
|
132
|
+
validate_name("database", 3, 256, name)
|
|
133
|
+
end
|
|
134
|
+
|
|
118
135
|
def self.validate_table_name(name)
|
|
119
|
-
|
|
136
|
+
validate_name("table", 3, 256, name)
|
|
120
137
|
end
|
|
121
138
|
|
|
122
139
|
def self.validate_result_set_name(name)
|
|
123
|
-
|
|
140
|
+
validate_name("result set", 3, 256, name)
|
|
124
141
|
end
|
|
125
142
|
|
|
126
143
|
def self.validate_column_name(name)
|
|
127
|
-
|
|
128
|
-
if name.empty?
|
|
129
|
-
raise "Empty column name is not allowed"
|
|
130
|
-
end
|
|
131
|
-
if 256 < name.length
|
|
132
|
-
raise "Column name must be to 256 characters, got #{name.length} characters."
|
|
133
|
-
end
|
|
134
|
-
unless name =~ /^([a-z0-9_]+)$/
|
|
135
|
-
raise "Column name must consist only of alphabets, numbers, '_'."
|
|
136
|
-
end
|
|
144
|
+
validate_name("column", 2, 256, name)
|
|
137
145
|
end
|
|
138
146
|
|
|
139
147
|
def self.normalize_database_name(name)
|
|
@@ -408,10 +416,11 @@ class API
|
|
|
408
416
|
query = m['query']
|
|
409
417
|
start_at = m['start_at']
|
|
410
418
|
end_at = m['end_at']
|
|
419
|
+
cpu_time = m['cpu_time']
|
|
411
420
|
result_url = m['result']
|
|
412
421
|
priority = m['priority']
|
|
413
422
|
retry_limit = m['retry_limit']
|
|
414
|
-
result << [job_id, type, status, query, start_at, end_at, result_url, priority, retry_limit, nil, database] # same as database
|
|
423
|
+
result << [job_id, type, status, query, start_at, end_at, cpu_time, result_url, priority, retry_limit, nil, database] # same as database
|
|
415
424
|
}
|
|
416
425
|
return result
|
|
417
426
|
end
|
|
@@ -433,6 +442,7 @@ class API
|
|
|
433
442
|
url = js['url']
|
|
434
443
|
start_at = js['start_at']
|
|
435
444
|
end_at = js['end_at']
|
|
445
|
+
cpu_time = js['cpu_time']
|
|
436
446
|
result = js['result']
|
|
437
447
|
hive_result_schema = (js['hive_result_schema'] || '')
|
|
438
448
|
if hive_result_schema.empty?
|
|
@@ -442,7 +452,7 @@ class API
|
|
|
442
452
|
end
|
|
443
453
|
priority = js['priority']
|
|
444
454
|
retry_limit = js['retry_limit']
|
|
445
|
-
return [type, query, status, url, debug, start_at, end_at, result, hive_result_schema, priority, retry_limit, nil, database] # same as above
|
|
455
|
+
return [type, query, status, url, debug, start_at, end_at, cpu_time, result, hive_result_schema, priority, retry_limit, nil, database] # same as above
|
|
446
456
|
end
|
|
447
457
|
|
|
448
458
|
def job_status(job_id)
|
|
@@ -1142,6 +1152,12 @@ class API
|
|
|
1142
1152
|
response = http.request(request)
|
|
1143
1153
|
end
|
|
1144
1154
|
|
|
1155
|
+
unless ENV['TD_CLIENT_DEBUG'].nil?
|
|
1156
|
+
puts "DEBUG: REST GET response:"
|
|
1157
|
+
puts "DEBUG: header: " + response.header.to_s
|
|
1158
|
+
puts "DEBUG: body: " + response.body.to_s
|
|
1159
|
+
end
|
|
1160
|
+
|
|
1145
1161
|
body = response.body
|
|
1146
1162
|
unless block
|
|
1147
1163
|
if ce = response.header['content-encoding']
|
|
@@ -1269,7 +1285,11 @@ class API
|
|
|
1269
1285
|
status_code = res.code.to_s
|
|
1270
1286
|
begin
|
|
1271
1287
|
js = JSON.load(res.body)
|
|
1272
|
-
|
|
1288
|
+
if js.nil?
|
|
1289
|
+
error_msg = res.message
|
|
1290
|
+
else
|
|
1291
|
+
error_msg = js['message'] || js['error']
|
|
1292
|
+
end
|
|
1273
1293
|
|
|
1274
1294
|
if klass
|
|
1275
1295
|
raise klass, "#{status_code}: #{msg}: #{error_msg}"
|
data/lib/td/client/model.rb
CHANGED
|
@@ -237,7 +237,7 @@ class Job < Model
|
|
|
237
237
|
STATUS_KILLED = "killed"
|
|
238
238
|
FINISHED_STATUS = [STATUS_SUCCESS, STATUS_ERROR, STATUS_KILLED]
|
|
239
239
|
|
|
240
|
-
def initialize(client, job_id, type, query, status=nil, url=nil, debug=nil, start_at=nil, end_at=nil, result=nil, result_url=nil, hive_result_schema=nil, priority=nil, retry_limit=nil, org_name=nil, db_name=nil)
|
|
240
|
+
def initialize(client, job_id, type, query, status=nil, url=nil, debug=nil, start_at=nil, end_at=nil, cpu_time=nil, result=nil, result_url=nil, hive_result_schema=nil, priority=nil, retry_limit=nil, org_name=nil, db_name=nil)
|
|
241
241
|
super(client)
|
|
242
242
|
@job_id = job_id
|
|
243
243
|
@type = type
|
|
@@ -247,6 +247,7 @@ class Job < Model
|
|
|
247
247
|
@debug = debug
|
|
248
248
|
@start_at = start_at
|
|
249
249
|
@end_at = end_at
|
|
250
|
+
@cpu_time = cpu_time
|
|
250
251
|
@result = result
|
|
251
252
|
@result_url = result_url
|
|
252
253
|
@hive_result_schema = hive_result_schema
|
|
@@ -267,35 +268,40 @@ class Job < Model
|
|
|
267
268
|
end
|
|
268
269
|
|
|
269
270
|
def query
|
|
270
|
-
update_status! unless @query
|
|
271
|
+
update_status! unless @query || finished?
|
|
271
272
|
@query
|
|
272
273
|
end
|
|
273
274
|
|
|
274
275
|
def status
|
|
275
|
-
update_status! unless @status
|
|
276
|
+
update_status! unless @status || finished?
|
|
276
277
|
@status
|
|
277
278
|
end
|
|
278
279
|
|
|
279
280
|
def url
|
|
280
|
-
update_status! unless @url
|
|
281
|
+
update_status! unless @url || finished?
|
|
281
282
|
@url
|
|
282
283
|
end
|
|
283
284
|
|
|
284
285
|
def debug
|
|
285
|
-
update_status! unless @debug
|
|
286
|
+
update_status! unless @debug || finished?
|
|
286
287
|
@debug
|
|
287
288
|
end
|
|
288
289
|
|
|
289
290
|
def start_at
|
|
290
|
-
update_status! unless @start_at
|
|
291
|
+
update_status! unless @start_at || finished?
|
|
291
292
|
@start_at && !@start_at.empty? ? Time.parse(@start_at) : nil
|
|
292
293
|
end
|
|
293
294
|
|
|
294
295
|
def end_at
|
|
295
|
-
update_status! unless @end_at
|
|
296
|
+
update_status! unless @end_at || finished?
|
|
296
297
|
@end_at && !@end_at.empty? ? Time.parse(@end_at) : nil
|
|
297
298
|
end
|
|
298
299
|
|
|
300
|
+
def cpu_time
|
|
301
|
+
update_status! unless @cpu_time || finished?
|
|
302
|
+
@cpu_time
|
|
303
|
+
end
|
|
304
|
+
|
|
299
305
|
def result
|
|
300
306
|
unless @result
|
|
301
307
|
return nil unless finished?
|
data/lib/td/client/version.rb
CHANGED
data/spec/td/client/api_spec.rb
CHANGED
|
@@ -51,6 +51,7 @@ describe API do
|
|
|
51
51
|
INVALID_NAMES.each_pair {|ng,ok|
|
|
52
52
|
API.normalize_table_name(ng).should == ok
|
|
53
53
|
}
|
|
54
|
+
# empty
|
|
54
55
|
lambda {
|
|
55
56
|
API.normalize_table_name('')
|
|
56
57
|
}.should raise_error(RuntimeError)
|
|
@@ -64,32 +65,116 @@ describe API do
|
|
|
64
65
|
end
|
|
65
66
|
|
|
66
67
|
describe 'validator' do
|
|
67
|
-
|
|
68
|
-
|
|
68
|
+
describe "'validate_database_name'" do
|
|
69
|
+
it 'should raise a ParameterValidationError exceptions' do
|
|
70
|
+
INVALID_NAMES.each_pair {|ng,ok|
|
|
71
|
+
lambda {
|
|
72
|
+
API.validate_database_name(ng)
|
|
73
|
+
}.should raise_error(ParameterValidationError)
|
|
74
|
+
}
|
|
75
|
+
# empty
|
|
69
76
|
lambda {
|
|
70
|
-
API.validate_database_name(
|
|
71
|
-
}.should raise_error(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
77
|
+
API.validate_database_name('')
|
|
78
|
+
}.should raise_error(ParameterValidationError)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it 'should return valid data' do
|
|
82
|
+
VALID_NAMES.each {|ok|
|
|
83
|
+
API.validate_database_name(ok).should == ok
|
|
84
|
+
}
|
|
85
|
+
end
|
|
76
86
|
end
|
|
77
87
|
|
|
78
|
-
|
|
79
|
-
|
|
88
|
+
describe "'validate_table_name'" do
|
|
89
|
+
it 'should raise a ParameterValidationError exception' do
|
|
90
|
+
INVALID_NAMES.each_pair {|ng,ok|
|
|
91
|
+
lambda {
|
|
92
|
+
API.validate_table_name(ng)
|
|
93
|
+
}.should raise_error(ParameterValidationError)
|
|
94
|
+
}
|
|
80
95
|
lambda {
|
|
81
|
-
API.validate_table_name(
|
|
82
|
-
}.should raise_error(
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
96
|
+
API.validate_table_name('')
|
|
97
|
+
}.should raise_error(ParameterValidationError)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it 'should return valid data' do
|
|
101
|
+
VALID_NAMES.each {|ok|
|
|
102
|
+
API.validate_database_name(ok).should == ok
|
|
103
|
+
}
|
|
104
|
+
end
|
|
87
105
|
end
|
|
88
106
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
107
|
+
describe "'validate_result_set_name'" do
|
|
108
|
+
it 'should raise a ParameterValidationError exception' do
|
|
109
|
+
INVALID_NAMES.each_pair {|ng,ok|
|
|
110
|
+
lambda {
|
|
111
|
+
API.validate_result_set_name(ng)
|
|
112
|
+
}.should raise_error(ParameterValidationError)
|
|
113
|
+
}
|
|
114
|
+
# empty
|
|
115
|
+
lambda {
|
|
116
|
+
API.validate_result_set_name('')
|
|
117
|
+
}.should raise_error(ParameterValidationError)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it 'should return valid data' do
|
|
121
|
+
VALID_NAMES.each {|ok|
|
|
122
|
+
API.validate_result_set_name(ok).should == ok
|
|
123
|
+
}
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
describe "'validate_column_name'" do
|
|
128
|
+
it 'should raise a ParameterValidationError exception' do
|
|
129
|
+
INVALID_NAMES.each_pair {|ng,ok|
|
|
130
|
+
lambda {
|
|
131
|
+
API.validate_column_name(ng)
|
|
132
|
+
}.should raise_error(ParameterValidationError)
|
|
133
|
+
}
|
|
134
|
+
# empty
|
|
135
|
+
lambda {
|
|
136
|
+
API.validate_column_name('')
|
|
137
|
+
}.should raise_error(ParameterValidationError)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it 'should return valid data' do
|
|
141
|
+
VALID_NAMES.each {|ok|
|
|
142
|
+
API.validate_column_name(ok).should == ok
|
|
143
|
+
}
|
|
144
|
+
# columns can be as short as 2 characters
|
|
145
|
+
API.validate_column_name('ab').should == 'ab'
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
describe "'generic validate_name'" do
|
|
151
|
+
it 'should raise a ParameterValidationError exception' do
|
|
152
|
+
INVALID_NAMES.each_pair {|ng,ok|
|
|
153
|
+
lambda {
|
|
154
|
+
API.validate_name("generic", 3, 256, ng)
|
|
155
|
+
}.should raise_error(ParameterValidationError)
|
|
156
|
+
}
|
|
157
|
+
# empty
|
|
158
|
+
lambda {
|
|
159
|
+
API.validate_name("generic", 3, 256, '')
|
|
160
|
+
}.should raise_error(ParameterValidationError)
|
|
161
|
+
# too short - one less than left limit
|
|
162
|
+
lambda {
|
|
163
|
+
API.validate_name("generic", 3, 256, 'ab')
|
|
164
|
+
}.should raise_error(ParameterValidationError)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it 'should return valid data' do
|
|
168
|
+
VALID_NAMES.each {|ok|
|
|
169
|
+
API.validate_name("generic", 3, 256, ok).should == ok
|
|
170
|
+
}
|
|
171
|
+
# esplore left boundary
|
|
172
|
+
API.validate_name("generic", 2, 256, 'ab').should == 'ab'
|
|
173
|
+
API.validate_name("generic", 1, 256, 'a').should == 'a'
|
|
174
|
+
# explore right boundary
|
|
175
|
+
API.validate_name("generic", 3, 256, 'a' * 256).should == 'a' * 256
|
|
176
|
+
API.validate_name("generic", 3, 128, 'a' * 128).should == 'a' * 128
|
|
177
|
+
end
|
|
93
178
|
end
|
|
94
179
|
end
|
|
95
180
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: td-client
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.8.
|
|
4
|
+
version: 0.8.59
|
|
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-
|
|
12
|
+
date: 2014-04-24 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: msgpack
|
|
@@ -191,7 +191,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
191
191
|
version: '0'
|
|
192
192
|
segments:
|
|
193
193
|
- 0
|
|
194
|
-
hash:
|
|
194
|
+
hash: 1351627692478107055
|
|
195
195
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
196
196
|
none: false
|
|
197
197
|
requirements:
|
|
@@ -200,7 +200,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
200
200
|
version: '0'
|
|
201
201
|
segments:
|
|
202
202
|
- 0
|
|
203
|
-
hash:
|
|
203
|
+
hash: 1351627692478107055
|
|
204
204
|
requirements: []
|
|
205
205
|
rubyforge_project:
|
|
206
206
|
rubygems_version: 1.8.23
|