td 0.11.2 → 0.11.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -84,13 +84,14 @@ module Command
84
84
  :Start => (start ? start.localtime : ''),
85
85
  :Elapsed => elapsed.rjust(11),
86
86
  :CPUTime => cpu_time.rjust(17),
87
+ :ResultSize => (job.result_size ? Command.humanize_bytesize(job.result_size, 2) : ""),
87
88
  :Priority => priority,
88
89
  :Result => job.result_url
89
90
  }
90
91
  }
91
92
 
92
93
  puts cmd_render_table(rows,
93
- :fields => [:JobID, :Status, :Start, :Elapsed, :CPUTime, :Priority, :Result, :Type, :Database, :Query],
94
+ :fields => [:JobID, :Status, :Start, :Elapsed, :CPUTime, :ResultSize, :Priority, :Result, :Type, :Database, :Query],
94
95
  :max_width => 1000,
95
96
  :render_format => op.render_format
96
97
  )
@@ -180,8 +181,13 @@ module Command
180
181
  puts "Destination : #{job.query}"
181
182
  end
182
183
  # if the job is done and is of type hive, show the Map-Reduce cumulated CPU time
183
- if job.finished? && [:hive].include?(job.type)
184
- puts "CPU time : #{Command.humanize_time(job.cpu_time, true)}"
184
+ if job.finished?
185
+ if [:hive].include?(job.type)
186
+ puts "CPU time : #{Command.humanize_time(job.cpu_time, true)}"
187
+ end
188
+ if [:hive, :pig, :impala, :presto].include?(job.type)
189
+ puts "Result size : #{Command.humanize_bytesize(job.result_size, 2)}"
190
+ end
185
191
  end
186
192
 
187
193
  if wait && !job.finished?
@@ -285,7 +291,7 @@ module Command
285
291
  def show_result(job, output, limit, format, render_opts={})
286
292
  if output
287
293
  write_result(job, output, limit, format, render_opts)
288
- puts "written to #{output} in #{format} format"
294
+ puts "\rwritten to #{output} in #{format} format" + " " * 50
289
295
  else
290
296
  # every format that is allowed on stdout
291
297
  render_result(job, limit, format, render_opts)
@@ -302,13 +308,20 @@ module Command
302
308
  open_file(output, "w") {|f|
303
309
  f.write "["
304
310
  n_rows = 0
305
- job.result_each {|row|
311
+ unless output.nil?
312
+ indicator = Command::SizeBasedDownloadProgressIndicator.new(
313
+ "NOTE: the job result is being written to #{output} in json format",
314
+ job.result_size, 0.1, 1)
315
+ end
316
+ job.result_each_with_compr_size {|row, compr_size|
317
+ indicator.update(compr_size) unless output.nil?
306
318
  f.write ",\n" if n_rows > 0
307
319
  f.write Yajl.dump(row)
308
320
  n_rows += 1
309
321
  break if output.nil? and !limit.nil? and n_rows == limit
310
322
  }
311
323
  f.write "]"
324
+ indicator.finish unless output.nil?
312
325
  }
313
326
  puts if output.nil?
314
327
 
@@ -318,15 +331,21 @@ module Command
318
331
 
319
332
  open_file(output, "w") {|f|
320
333
  writer = CSV.new(f)
321
- n_rows = 0
322
334
  # output headers
323
335
  if render_opts[:header] && job.hive_result_schema
324
- writer << job.hive_result_schema.map {|name,type|
336
+ writer << job.hive_result_schema.map {|name, type|
325
337
  name
326
338
  }
327
339
  end
328
340
  # output data
329
- job.result_each {|row|
341
+ n_rows = 0
342
+ unless output.nil?
343
+ indicator = Command::SizeBasedDownloadProgressIndicator.new(
344
+ "NOTE: the job result is being written to #{output} in csv format",
345
+ job.result_size, 0.1, 1)
346
+ end
347
+ job.result_each_with_compr_size {|row, compr_size|
348
+ indicator.update(compr_size) unless output.nil?
330
349
  # TODO limit the # of columns
331
350
  writer << row.map {|col|
332
351
  dump_column(col)
@@ -335,6 +354,7 @@ module Command
335
354
  writer.flush if n_rows % 100 == 0 # flush every 100 recods
336
355
  break if output.nil? and !limit.nil? and n_rows == limit
337
356
  }
357
+ indicator.finish unless output.nil?
338
358
  }
339
359
 
340
360
  when 'tsv'
@@ -350,7 +370,13 @@ module Command
350
370
  end
351
371
  # output data
352
372
  n_rows = 0
353
- job.result_each {|row|
373
+ unless output.nil?
374
+ indicator = Command::SizeBasedDownloadProgressIndicator.new(
375
+ "NOTE: the job result is being written to #{output} in tsv format",
376
+ job.result_size, 0.1, 1)
377
+ end
378
+ job.result_each_with_compr_size {|row, compr_size|
379
+ indicator.update(compr_size) unless output.nil?
354
380
  n_cols = 0
355
381
  row.each {|col|
356
382
  f.write "\t" if n_cols > 0
@@ -363,6 +389,7 @@ module Command
363
389
  f.flush if n_rows % 100 == 0 # flush every 100 recods
364
390
  break if output.nil? and !limit.nil? and n_rows == limit
365
391
  }
392
+ indicator.finish unless output.nil?
366
393
  }
367
394
 
368
395
  # these last 2 formats are only valid if writing the result to file through the -o/--output option.
@@ -373,7 +400,13 @@ module Command
373
400
  "Format 'msgpack' does not support writing to stdout"
374
401
  end
375
402
  open_file(output, "wb") {|f|
376
- job.result_format('msgpack', f)
403
+ indicator = Command::SizeBasedDownloadProgressIndicator.new(
404
+ "NOTE: the job result is being written to #{output} in msgpack format",
405
+ job.result_size, 0.1, 1)
406
+ job.result_format('msgpack', f) {|compr_size|
407
+ indicator.update(compr_size)
408
+ }
409
+ indicator.finish
377
410
  }
378
411
 
379
412
  when 'msgpack.gz'
@@ -382,7 +415,13 @@ module Command
382
415
  "Format 'msgpack' does not support writing to stdout"
383
416
  end
384
417
  open_file(output, "wb") {|f|
385
- job.result_format('msgpack.gz', f)
418
+ indicator = Command::SizeBasedDownloadProgressIndicator.new(
419
+ "NOTE: the job result is being written to #{output} in msgpack.gz format",
420
+ job.result_size, 0.1, 1)
421
+ job.result_format('msgpack.gz', f) {|compr_size|
422
+ indicator.update(compr_size)
423
+ }
424
+ indicator.finish
386
425
  }
387
426
 
388
427
  else
@@ -411,9 +450,11 @@ module Command
411
450
  # display result in tabular format
412
451
  rows = []
413
452
  n_rows = 0
414
- print "WARNING: the query result is being downloaded...\r"
415
- job.result_each {|row|
416
- # TODO limit number of rows to show
453
+
454
+ indicator = Command::SizeBasedDownloadProgressIndicator.new(
455
+ "WARNING: the job result is being downloaded...", job.result_size, 0.1, 1)
456
+ job.result_each_with_compr_size {|row, compr_size|
457
+ indicator.update(compr_size)
417
458
  rows << row.map {|v|
418
459
  dump_column(v)
419
460
  }
@@ -427,7 +468,8 @@ module Command
427
468
  render_opts[:change_fields] = job.hive_result_schema.map { |name,type| name }
428
469
  end
429
470
 
430
- puts cmd_render_table(rows, render_opts)
471
+ print "\r" + " " * 50
472
+ puts "\r" + cmd_render_table(rows, render_opts)
431
473
  else
432
474
  # display result in any of: json, csv, tsv.
433
475
  # msgpack and mspgpack.gz are not supported for stdout output
@@ -3,17 +3,19 @@ module Command
3
3
  module List
4
4
 
5
5
  class CommandParser < OptionParser
6
- def initialize(name, req_args, opt_args, varlen, argv)
6
+ def initialize(name, req_args, opt_args, varlen, argv, req_conn)
7
7
  super()
8
+ @name = name
8
9
  @req_args = req_args
9
10
  @opt_args = opt_args
10
11
  @varlen = varlen
11
12
  @argv = argv
12
13
  @has_options = false
13
14
  @message = ''
15
+ @cmd_requires_connectivity = req_conn
14
16
  end
15
17
 
16
- attr_accessor :message
18
+ attr_accessor :message, :name, :cmd_requires_connectivity
17
19
 
18
20
  def on(*argv)
19
21
  @has_options = true
@@ -51,15 +53,16 @@ module List
51
53
  end
52
54
 
53
55
  class CommandOption
54
- def initialize(name, args, description, examples)
56
+ def initialize(name, args, description, examples = [], req_conn = true)
55
57
  @name = name
56
58
  @args = args
57
59
  @description = description.to_s
58
60
  @examples = examples
61
+ @req_conn = req_conn
59
62
  @override_message = nil
60
63
  end
61
64
 
62
- attr_reader :name, :args, :description, :examples
65
+ attr_reader :name, :args, :description, :examples, :req_conn
63
66
  attr_accessor :override_message
64
67
 
65
68
  def compile!
@@ -84,7 +87,7 @@ module List
84
87
 
85
88
  def create_optparse(argv)
86
89
  compile!
87
- op = CommandParser.new(@name, @req_args, @opt_args, @varlen, argv)
90
+ op = CommandParser.new(@name, @req_args, @opt_args, @varlen, argv, @req_conn)
88
91
 
89
92
  message = "usage:\n"
90
93
  message << " $ #{File.basename($0)} #{@usage_args}\n"
@@ -129,8 +132,8 @@ module List
129
132
  HELP_EXCLUDE = [/^help/, /^account/, /^update/, /^user/, /^acl/]
130
133
  USAGE_EXCLUDE = [/bulk_import:upload_part\z/, /bulk_import:delete_part\z/]
131
134
 
132
- def self.add_list(name, args, description, *examples)
133
- LIST << COMMAND[name] = CommandOption.new(name, args, description, examples)
135
+ def self.add_list(name, args, description, examples = [], cmd_req_conn = true)
136
+ LIST << COMMAND[name] = CommandOption.new(name, args, description, examples, cmd_req_conn)
134
137
  end
135
138
 
136
139
  def self.add_alias(new_cmd, old_cmd)
@@ -157,7 +160,7 @@ module List
157
160
  require "td/command/#{group}"
158
161
  cmd = name.gsub(/[\:\-]/, '_')
159
162
  m = Object.new.extend(Command).method(cmd)
160
- return Proc.new {|args| m.call(c.create_optparse(args)) }
163
+ return Proc.new { |args| m.call(c.create_optparse(args)) }, c.req_conn
161
164
  end
162
165
  nil
163
166
  end
@@ -213,85 +216,85 @@ module List
213
216
  }
214
217
  end
215
218
 
216
- add_list 'db:list', %w[], 'Show list of tables in a database', 'db:list', 'dbs'
217
- add_list 'db:show', %w[db], 'Describe information of a database', 'db example_db'
218
- add_list 'db:create', %w[db], 'Create a database', 'db:create example_db'
219
- add_list 'db:delete', %w[db], 'Delete a database', 'db:delete example_db'
220
-
221
- add_list 'table:list', %w[db?], 'Show list of tables', 'table:list', 'table:list example_db', 'tables'
222
- add_list 'table:show', %w[db table], 'Describe information of a table', 'table example_db table1'
223
- add_list 'table:create', %w[db table], 'Create a table', 'table:create example_db table1'
224
- add_list 'table:delete', %w[db table], 'Delete a table', 'table:delete example_db table1'
225
- add_list 'table:import', %w[db table files_], 'Parse and import files to a table', 'table:import example_db table1 --apache access.log', 'table:import example_db table1 --json -t time - < test.json'
226
- add_list 'table:export', %w[db table], 'Dump logs in a table to the specified storage', 'table:export example_db table1 --s3-bucket mybucket -k KEY_ID -s SECRET_KEY'
227
- add_list 'table:swap', %w[db table1 table2], 'Swap names of two tables', 'table:swap example_db table1 table2'
228
- add_list 'table:tail', %w[db table], 'Get recently imported logs', 'table:tail example_db table1', 'table:tail example_db table1 -t "2011-01-02 03:04:05" -n 30'
229
- add_list 'table:partial_delete', %w[db table], 'Delete logs from the table within the specified time range', 'table:partial_delete example_db table1 --from 1341000000 --to 1341003600'
230
- add_list 'table:expire', %w[db table expire_days], 'Expire data in table after specified number of days', 'table:expire example_db table1 30'
231
-
232
- add_list 'bulk_import:list', %w[], 'List bulk import sessions', 'bulk_import:list'
233
- add_list 'bulk_import:show', %w[name], 'Show list of uploaded parts', 'bulk_import:show'
234
- add_list 'bulk_import:create', %w[name db table], 'Create a new bulk import session to the the table', 'bulk_import:create logs_201201 example_db event_logs'
235
- add_list 'bulk_import:prepare_parts', %w[files_], 'Convert files into part file format', 'bulk_import:prepare_parts logs/*.csv --format csv --columns time,uid,price,count --time-column "time" -o parts/'
236
- add_list 'bulk_import:upload_part', %w[name id path.msgpack.gz], 'Upload or re-upload a file into a bulk import session', 'bulk_import:upload_part logs_201201 01h data-201201-01.msgpack.gz'
237
- add_list 'bulk_import:upload_parts', %w[name files_], 'Upload or re-upload files into a bulk import session', 'bulk_import:upload_parts parts/* --parallel 4'
238
- add_list 'bulk_import:delete_part', %w[name id], 'Delete a uploaded file from a bulk import session', 'bulk_import:delete_part logs_201201 01h'
239
- add_list 'bulk_import:delete_parts', %w[name ids_], 'Delete uploaded files from a bulk import session', 'bulk_import:delete_parts logs_201201 01h 02h 03h'
240
- add_list 'bulk_import:perform', %w[name], 'Start to validate and convert uploaded files', 'bulk_import:perform logs_201201'
241
- add_list 'bulk_import:error_records', %w[name], 'Show records which did not pass validations', 'bulk_import:error_records logs_201201'
242
- add_list 'bulk_import:commit', %w[name], 'Start to commit a performed bulk import session', 'bulk_import:commit logs_201201'
243
- add_list 'bulk_import:delete', %w[name], 'Delete a bulk import session', 'bulk_import:delete logs_201201'
244
- add_list 'bulk_import:freeze', %w[name], 'Reject succeeding uploadings to a bulk import session', 'bulk_import:freeze logs_201201'
245
- add_list 'bulk_import:unfreeze', %w[name], 'Unfreeze a frozen bulk import session', 'bulk_import:unfreeze logs_201201'
246
-
247
- add_list 'import:list', %w[], 'List bulk import sessions', 'import:list'
248
- add_list 'import:show', %w[name], 'Show list of uploaded parts', 'import:show'
249
- add_list 'import:create', %w[name db table], 'Create a new bulk import session to the the table', 'import:create logs_201201 example_db event_logs'
250
- add_list 'import:jar_version', %w[], 'Show import jar version', 'import:jar_version'
251
- add_list 'import:jar_update', %w[], 'Update import jar to the latest version', 'import:jar_update'
252
- add_list 'import:prepare', %w[files_], 'Convert files into part file format', 'import:prepare logs/*.csv --format csv --columns time,uid,price,count --time-column "time" -o parts/'
253
- add_list 'import:upload', %w[name files_], 'Upload or re-upload files into a bulk import session', 'import:upload parts/* --parallel 4'
254
- add_list 'import:auto', %w[name files_], 'Upload files and automatically perform and commit the data', 'import:auto parts/* --parallel 4'
255
- add_list 'import:perform', %w[name], 'Start to validate and convert uploaded files', 'import:perform logs_201201'
256
- add_list 'import:error_records', %w[name], 'Show records which did not pass validations', 'import:error_records logs_201201'
257
- add_list 'import:commit', %w[name], 'Start to commit a performed bulk import session', 'import:commit logs_201201'
258
- add_list 'import:delete', %w[name], 'Delete a bulk import session', 'import:delete logs_201201'
259
- add_list 'import:freeze', %w[name], 'Reject succeeding uploadings to a bulk import session', 'import:freeze logs_201201'
260
- add_list 'import:unfreeze', %w[name], 'Unfreeze a frozen bulk import session', 'import:unfreeze logs_201201'
261
-
262
- add_list 'result:list', %w[], 'Show list of result URLs', 'result:list', 'results'
263
- add_list 'result:show', %w[name], 'Describe information of a result URL', 'result name'
264
- add_list 'result:create', %w[name URL], 'Create a result URL', 'result:create name mysql://my-server/mydb'
265
- add_list 'result:delete', %w[name], 'Delete a result URL', 'result:delete name'
266
-
267
- add_list 'status', %w[], 'Show schedules, jobs, tables and results', 'status', 's'
268
-
269
- add_list 'schema:show', %w[db table], 'Show schema of a table', 'schema example_db table1'
270
- add_list 'schema:set', %w[db table columns_?], 'Set new schema on a table', 'schema:set example_db table1 user:string size:int'
271
- add_list 'schema:add', %w[db table columns_], 'Add new columns to a table', 'schema:add example_db table1 user:string size:int'
272
- add_list 'schema:remove', %w[db table columns_], 'Remove columns from a table', 'schema:remove example_db table1 user size'
273
-
274
- add_list 'sched:list', %w[], 'Show list of schedules', 'sched:list', 'scheds'
275
- add_list 'sched:create', %w[name cron sql?], 'Create a schedule', 'sched:create sched1 "0 * * * *" -d example_db "select count(*) from table1" -r rset1',
276
- 'sched:create sched1 "0 * * * *" -d example_db -q query.txt -r rset2'
277
- add_list 'sched:delete', %w[name], 'Delete a schedule', 'sched:delete sched1'
278
- add_list 'sched:update', %w[name], 'Modify a schedule', 'sched:update sched1 -s "0 */2 * * *" -d my_db -t "Asia/Tokyo" -D 3600'
279
- add_list 'sched:history', %w[name max?], 'Show history of scheduled queries', 'sched sched1 --page 1'
280
- add_list 'sched:run', %w[name time], 'Run scheduled queries for the specified time', 'sched:run sched1 "2013-01-01 00:00:00" -n 6'
281
-
282
- add_list 'query', %w[sql?], 'Issue a query', 'query -d example_db -w -r rset1 "select count(*) from table1"',
283
- 'query -d example_db -w -r rset1 -q query.txt'
284
-
285
- add_list 'job:show', %w[job_id], 'Show status and result of a job', 'job:show 1461'
286
- add_list 'job:status', %w[job_id], 'Show status progress of a job', 'job:status 1461'
287
- add_list 'job:list', %w[max?], 'Show list of jobs', 'jobs', 'jobs --page 1'
288
- add_list 'job:kill', %w[job_id], 'Kill or cancel a job', 'job:kill 1461'
219
+ add_list 'db:list', %w[], 'Show list of tables in a database', ['db:list', 'dbs']
220
+ add_list 'db:show', %w[db], 'Describe information of a database', ['db example_db']
221
+ add_list 'db:create', %w[db], 'Create a database', ['db:create example_db']
222
+ add_list 'db:delete', %w[db], 'Delete a database', ['db:delete example_db']
223
+
224
+ add_list 'table:list', %w[db?], 'Show list of tables', ['table:list', 'table:list example_db', 'tables']
225
+ add_list 'table:show', %w[db table], 'Describe information of a table', ['table example_db table1']
226
+ add_list 'table:create', %w[db table], 'Create a table', ['table:create example_db table1']
227
+ add_list 'table:delete', %w[db table], 'Delete a table', ['table:delete example_db table1']
228
+ add_list 'table:import', %w[db table files_], 'Parse and import files to a table', ['table:import example_db table1 --apache access.log', 'table:import example_db table1 --json -t time - < test.json']
229
+ add_list 'table:export', %w[db table], 'Dump logs in a table to the specified storage', ['table:export example_db table1 --s3-bucket mybucket -k KEY_ID -s SECRET_KEY']
230
+ add_list 'table:swap', %w[db table1 table2], 'Swap names of two tables', ['table:swap example_db table1 table2']
231
+ add_list 'table:tail', %w[db table], 'Get recently imported logs', ['table:tail example_db table1', 'table:tail example_db table1 -t "2011-01-02 03:04:05" -n 30']
232
+ add_list 'table:partial_delete', %w[db table], 'Delete logs from the table within the specified time range', ['table:partial_delete example_db table1 --from 1341000000 --to 1341003600']
233
+ add_list 'table:expire', %w[db table expire_days], 'Expire data in table after specified number of days', ['table:expire example_db table1 30']
234
+
235
+ add_list 'bulk_import:list', %w[], 'List bulk import sessions', ['bulk_import:list']
236
+ add_list 'bulk_import:show', %w[name], 'Show list of uploaded parts', ['bulk_import:show']
237
+ add_list 'bulk_import:create', %w[name db table], 'Create a new bulk import session to the the table', ['bulk_import:create logs_201201 example_db event_logs']
238
+ add_list 'bulk_import:prepare_parts', %w[files_], 'Convert files into part file format', ['bulk_import:prepare_parts logs/*.csv --format csv --columns time,uid,price,count --time-column "time" -o parts/']
239
+ add_list 'bulk_import:upload_part', %w[name id path.msgpack.gz], 'Upload or re-upload a file into a bulk import session', ['bulk_import:upload_part logs_201201 01h data-201201-01.msgpack.gz']
240
+ add_list 'bulk_import:upload_parts', %w[name files_], 'Upload or re-upload files into a bulk import session', ['bulk_import:upload_parts parts/* --parallel 4']
241
+ add_list 'bulk_import:delete_part', %w[name id], 'Delete a uploaded file from a bulk import session', ['bulk_import:delete_part logs_201201 01h']
242
+ add_list 'bulk_import:delete_parts', %w[name ids_], 'Delete uploaded files from a bulk import session', ['bulk_import:delete_parts logs_201201 01h 02h 03h']
243
+ add_list 'bulk_import:perform', %w[name], 'Start to validate and convert uploaded files', ['bulk_import:perform logs_201201']
244
+ add_list 'bulk_import:error_records', %w[name], 'Show records which did not pass validations', ['bulk_import:error_records logs_201201']
245
+ add_list 'bulk_import:commit', %w[name], 'Start to commit a performed bulk import session', ['bulk_import:commit logs_201201']
246
+ add_list 'bulk_import:delete', %w[name], 'Delete a bulk import session', ['bulk_import:delete logs_201201']
247
+ add_list 'bulk_import:freeze', %w[name], 'Reject succeeding uploadings to a bulk import session', ['bulk_import:freeze logs_201201']
248
+ add_list 'bulk_import:unfreeze', %w[name], 'Unfreeze a frozen bulk import session', ['bulk_import:unfreeze logs_201201']
249
+
250
+ add_list 'import:list', %w[], 'List bulk import sessions', ['import:list']
251
+ add_list 'import:show', %w[name], 'Show list of uploaded parts', ['import:show']
252
+ add_list 'import:create', %w[name db table], 'Create a new bulk import session to the the table', ['import:create logs_201201 example_db event_logs']
253
+ add_list 'import:jar_version', %w[], 'Show import jar version', ['import:jar_version'], false
254
+ add_list 'import:jar_update', %w[], 'Update import jar to the latest version', ['import:jar_update']
255
+ add_list 'import:prepare', %w[files_], 'Convert files into part file format', ['import:prepare logs/*.csv --format csv --columns time,uid,price,count --time-column "time" -o parts/'], false
256
+ add_list 'import:upload', %w[name files_], 'Upload or re-upload files into a bulk import session', ['import:upload parts/* --parallel 4']
257
+ add_list 'import:auto', %w[name files_], 'Upload files and automatically perform and commit the data', ['import:auto parts/* --parallel 4']
258
+ add_list 'import:perform', %w[name], 'Start to validate and convert uploaded files', ['import:perform logs_201201']
259
+ add_list 'import:error_records', %w[name], 'Show records which did not pass validations', ['import:error_records logs_201201']
260
+ add_list 'import:commit', %w[name], 'Start to commit a performed bulk import session', ['import:commit logs_201201']
261
+ add_list 'import:delete', %w[name], 'Delete a bulk import session', ['import:delete logs_201201']
262
+ add_list 'import:freeze', %w[name], 'Reject succeeding uploadings to a bulk import session', ['import:freeze logs_201201']
263
+ add_list 'import:unfreeze', %w[name], 'Unfreeze a frozen bulk import session', ['import:unfreeze logs_201201']
264
+
265
+ add_list 'result:list', %w[], 'Show list of result URLs', ['result:list', 'results']
266
+ add_list 'result:show', %w[name], 'Describe information of a result URL', ['result name']
267
+ add_list 'result:create', %w[name URL], 'Create a result URL', ['result:create name mysql://my-server/mydb']
268
+ add_list 'result:delete', %w[name], 'Delete a result URL', ['result:delete name']
269
+
270
+ add_list 'status', %w[], 'Show schedules, jobs, tables and results', ['status', 's']
271
+
272
+ add_list 'schema:show', %w[db table], 'Show schema of a table', ['schema example_db table1']
273
+ add_list 'schema:set', %w[db table columns_?], 'Set new schema on a table', ['schema:set example_db table1 user:string size:int']
274
+ add_list 'schema:add', %w[db table columns_], 'Add new columns to a table', ['schema:add example_db table1 user:string size:int']
275
+ add_list 'schema:remove', %w[db table columns_], 'Remove columns from a table', ['schema:remove example_db table1 user size']
276
+
277
+ add_list 'sched:list', %w[], 'Show list of schedules', ['sched:list', 'scheds']
278
+ add_list 'sched:create', %w[name cron sql?], 'Create a schedule', ['sched:create sched1 "0 * * * *" -d example_db "select count(*) from table1" -r rset1',
279
+ 'sched:create sched1 "0 * * * *" -d example_db -q query.txt -r rset2']
280
+ add_list 'sched:delete', %w[name], 'Delete a schedule', ['sched:delete sched1']
281
+ add_list 'sched:update', %w[name], 'Modify a schedule', ['sched:update sched1 -s "0 */2 * * *" -d my_db -t "Asia/Tokyo" -D 3600']
282
+ add_list 'sched:history', %w[name max?], 'Show history of scheduled queries', ['sched sched1 --page 1']
283
+ add_list 'sched:run', %w[name time], 'Run scheduled queries for the specified time', ['sched:run sched1 "2013-01-01 00:00:00" -n 6']
284
+
285
+ add_list 'query', %w[sql?], 'Issue a query', ['query -d example_db -w -r rset1 "select count(*) from table1"',
286
+ 'query -d example_db -w -r rset1 -q query.txt']
287
+
288
+ add_list 'job:show', %w[job_id], 'Show status and result of a job', ['job:show 1461']
289
+ add_list 'job:status', %w[job_id], 'Show status progress of a job', ['job:status 1461']
290
+ add_list 'job:list', %w[max?], 'Show list of jobs', ['jobs', 'jobs --page 1']
291
+ add_list 'job:kill', %w[job_id], 'Kill or cancel a job', ['job:kill 1461']
289
292
 
290
293
  add_list 'account', %w[user_name?], 'Setup a Treasure Data account'
291
294
  add_list 'account:usage', %w[user_name?], 'Show resource usage information'
292
295
  add_list 'password:change', %w[], 'Change password'
293
- add_list 'apikey:show', %w[], 'Show Treasure Data API key'
294
- add_list 'apikey:set', %w[apikey], 'Set Treasure Data API key'
296
+ add_list 'apikey:show', %w[], 'Show Treasure Data API key', [], false
297
+ add_list 'apikey:set', %w[apikey], 'Set Treasure Data API key', [], false
295
298
 
296
299
  add_list 'user:list', %w[], 'Show list of users'
297
300
  add_list 'user:show', %w[name], 'Show an user'
@@ -308,12 +311,12 @@ module List
308
311
  # TODO acl:test
309
312
 
310
313
  add_list 'server:status', %w[], 'Show status of the Treasure Data server'
311
- add_list 'server:endpoint', %w[api_endpoint], "Set the Treasure Data API server's endpoint (must be a valid URI)", "td server:endpoint 'https://api.treasuredata.com'"
314
+ add_list 'server:endpoint', %w[api_endpoint], "Set the Treasure Data API server's endpoint (must be a valid URI)", ["td server:endpoint 'https://api.treasuredata.com'"]
312
315
 
313
- add_list 'sample:apache', %w[path.json], 'Create a sample log file'
316
+ add_list 'sample:apache', %w[path.json], 'Create a sample log file', [], false
314
317
 
315
- add_list 'help:all', %w[], 'Show usage of all commands'
316
- add_list 'help', %w[command], 'Show usage of a command'
318
+ add_list 'help:all', %w[], 'Show usage of all commands', [], false
319
+ add_list 'help', %w[command], 'Show usage of a command', [], false
317
320
 
318
321
  add_list 'update', %w[], 'Update td and related libraries for TreasureData toolbelt'
319
322
 
@@ -59,9 +59,9 @@ Type 'td help COMMAND' for more information on a specific command.
59
59
  EOF
60
60
  if errmsg
61
61
  puts "Error: #{errmsg}"
62
- exit 1
62
+ return 1
63
63
  else
64
- exit 0
64
+ return 0
65
65
  end
66
66
  end
67
67
  end
@@ -104,17 +104,17 @@ EOF
104
104
  #}
105
105
 
106
106
  op.on('-h', '--help', "show help") {
107
- usage nil
107
+ return usage nil
108
108
  }
109
109
 
110
110
  op.on('--version', "show version") {
111
111
  puts op.version
112
- exit
112
+ return 0
113
113
  }
114
114
 
115
115
  begin
116
116
  op.order!(argv)
117
- usage nil if argv.empty?
117
+ return usage nil if argv.empty?
118
118
  cmd = argv.shift
119
119
 
120
120
  # NOTE: these information are loaded from by each command through
@@ -135,7 +135,7 @@ EOF
135
135
  Config.secure = false
136
136
  end
137
137
  rescue
138
- usage $!.to_s
138
+ return usage $!.to_s
139
139
  end
140
140
 
141
141
  require 'td/command/list'
@@ -144,37 +144,49 @@ EOF
144
144
  Encoding.default_external = 'UTF-8' if Encoding.respond_to?(:default_external)
145
145
  end
146
146
 
147
- method = Command::List.get_method(cmd)
147
+ method, cmd_req_connectivity = Command::List.get_method(cmd)
148
148
  unless method
149
149
  $stderr.puts "'#{cmd}' is not a td command. Run '#{$prog}' to show the list."
150
150
  Command::List.show_guess(cmd)
151
- exit 1
151
+ return 1
152
152
  end
153
153
 
154
154
  begin
155
+ # test the connectivity with the API endpoint
156
+ if cmd_req_connectivity && Config.cl_endpoint
157
+ Command.test_api_endpoint(Config.endpoint)
158
+ end
155
159
  method.call(argv)
156
160
  rescue ConfigError
157
161
  $stderr.puts "TreasureData account is not configured yet."
158
162
  $stderr.puts "Run '#{$prog} account' first."
159
163
  rescue => e
160
- # work in progress look ahead development: new exceptions are rendered as simple
161
- # error messages unless the TD_TOOLBELT_DEBUG variable is not empty.
162
- # List of new exceptions:
163
- # => ParameterConfigurationError
164
- # => BulkImportExecutionError
165
- # => UpUpdateError
164
+ # known exceptions are rendered as simple error messages unless the
165
+ # TD_TOOLBELT_DEBUG variable is set or the -v / --verbose option is used.
166
+ # List of known exceptions:
167
+ # => ParameterConfigurationError
168
+ # => BulkImportExecutionError
169
+ # => UpUpdateError
170
+ # => ImportError
166
171
  require 'td/client/api'
167
- # => APIError
168
- unless [ParameterConfigurationError, BulkImportExecutionError, UpdateError,
169
- APIError]
170
- .include?(e.class) && ENV['TD_TOOLBELT_DEBUG'].nil?
172
+ # => APIError
173
+ # => ForbiddenError
174
+ # => NotFoundError
175
+ # => AuthError
176
+ if ![ParameterConfigurationError, BulkImportExecutionError, UpdateError, ImportError,
177
+ APIError, ForbiddenError, NotFoundError, AuthError].include?(e.class) ||
178
+ !ENV['TD_TOOLBELT_DEBUG'].nil? || $verbose
171
179
  $stderr.puts "Error #{$!.class}: backtrace:"
172
- $!.backtrace.each {|b|
173
- $stderr.puts " #{b}"
180
+ $!.backtrace.each {|bt|
181
+ $stderr.puts " #{bt}"
174
182
  }
175
183
  puts ""
176
184
  end
177
- puts "Error: " + $!.to_s
185
+ print "Error: "
186
+ if [ForbiddenError, NotFoundError, AuthError].include?(e.class)
187
+ print "#{e.class} - "
188
+ end
189
+ puts $!.to_s
178
190
 
179
191
  require 'socket'
180
192
  if e.is_a?(::SocketError)
@@ -136,6 +136,7 @@ module Command
136
136
  def sched_update(op)
137
137
  require 'td/command/job' # job_priority_id_of
138
138
 
139
+ newname = nil
139
140
  cron = nil
140
141
  sql = nil
141
142
  db_name = nil
@@ -146,6 +147,9 @@ module Command
146
147
  retry_limit = nil
147
148
  type = nil
148
149
 
150
+ op.on('-n', '--newname NAME', 'change the schedule\'s name') {|n|
151
+ newname = n
152
+ }
149
153
  op.on('-s', '--schedule CRON', 'change the schedule') {|s|
150
154
  cron = s
151
155
  }
@@ -183,10 +187,10 @@ module Command
183
187
  type = s
184
188
  }
185
189
 
186
-
187
- name = op.cmd_parse
190
+ curname = op.cmd_parse
188
191
 
189
192
  params = {}
193
+ params['name'] = newname if newname
190
194
  params['cron'] = cron if cron
191
195
  params['query'] = sql if sql
192
196
  params['database'] = db_name if db_name
@@ -205,15 +209,19 @@ module Command
205
209
  client = get_client
206
210
 
207
211
  begin
208
- client.update_schedule(name, params)
212
+ client.update_schedule(curname, params)
209
213
  rescue NotFoundError
210
214
  cmd_debug_error $!
211
- $stderr.puts "Schedule '#{name}' does not exist."
215
+ $stderr.puts "Schedule '#{curname}' does not exist."
212
216
  $stderr.puts "Use '#{$prog} " + Config.cl_options_string + "sched:list' to show list of the schedules."
213
217
  exit 1
214
218
  end
215
219
 
216
- $stderr.puts "Schedule '#{name}' is updated."
220
+ if newname && curname != newname
221
+ puts "Schedule '#{curname}' is updated and its name changed to '#{newname}'."
222
+ else
223
+ puts "Schedule '#{curname}' is updated."
224
+ end
217
225
  end
218
226
 
219
227
  def sched_history(op)
@@ -12,13 +12,16 @@ module Command
12
12
  def server_endpoint(op)
13
13
  endpoint = op.cmd_parse
14
14
 
15
- Command.validate_api_endpoint(endpoint)
16
-
17
15
  if Config.cl_endpoint and endpoint != Config.endpoint
18
16
  raise ParameterConfigurationError,
19
- "You specified the API server endpoint in the command options as well (-e / --endpoint option) but it does not match the value provided to the 'server:endpoint' command. Please remove the option or ensure the endpoints URLs match each other."
17
+ "You specified the API server endpoint in the command options as well (-e / --endpoint " +
18
+ "option) but it does not match the value provided to the 'server:endpoint' command. " +
19
+ "Please remove the option or ensure the endpoints URLs match each other."
20
20
  end
21
21
 
22
+ Command.validate_api_endpoint(endpoint)
23
+ Coomand.test_api_endpoint(endpoint)
24
+
22
25
  conf = nil
23
26
  begin
24
27
  conf = Config.read